我理解在Clojure中,Scala中的flatMap
等效于mapcat
。
我有一个暗示,mapcat
在clojure中仅适用于序列,而不像Scala中的flatMap
更灵活。
我的问题是 - 在Clojure中的mapcat
与Scala中的flatMap
之间的区别是什么?
假设:
flatMap
个功能的子集。 答案 0 :(得分:4)
在标准Scala库中:Responder
,Future
,Parser
,ControlContext
。它们都不是序列或特别是序列。 ParseResult
也略有不同。
答案 1 :(得分:4)
我对Scala有点了解,但在我看来,flatMap是monad中的Scala绑定函数,而mapcat是Clojure中序列monad的绑定函数的可能实现。所以序列也是如此。
但是Scala例如对Futures有一个flatMap函数:它需要一个future和一个映射函数,并返回一个在输入未来完成后将完成的未来。这个操作在Clojure中似乎不是一个简单的mapcat。可以通过这种方式实现
(defn flat-map [f mv] (mapcat (fn [v] (future (f @v))) mv))
所以,不。它们的运作方式并不相同。在Scala中,flatMap是不同函数的通用名称,例如Futures的flatMap坐标输入和输出期货。 Clojure中的一个简单的mapcat不起作用,因为它不会返回未来。
答案 2 :(得分:3)
他们看起来非常相似,似乎也在做同样的事情。从查看文档和examples我看不到功能上的差异。
mapcat
适用于序列,几乎每个clojure数据类型都可以是一个序列。如果您传递的内容不是seq
到mapcat
,它会自动调用seq,因此实际上您可以将所有clojure值传递给mapcat 。如果要迭代树,则需要调用prewalk
或postwalk
来指定遍历顺序。
答案 3 :(得分:1)
真正的区别是flatMap在类型上是多态的,而mapcat不是。因此,任何类型都可以决定提供类似行为的“ flatMap”。这就是让Futures成为flatMapable之类的方式。
在Clojure中,mapcat特定于seqable类型。可以将任何可序列化的序列强制转换为一个序列,并且可以映射和连接所有序列。 mapcat实现将检查输入是否可排序,如果是,则将在其上调用seq以将其强制为序列,然后它将映射并分配该序列并为您提供序列。您不会得到原始类型的结果。
在Scala中,如果实现IterableLike特征(我认为这是正确的接口),则将获得默认的flatMap实现,有点像Clojure减去强制序列化。但是,许多类型还提供了flatMap的自定义实现,以这种方式使其具有通用性。