Clojure中的mapcat和Scala中的flatMap在操作方面有什么区别



我知道Scala中flatMap的等价物是Clojure中的mapcat

我知道clojure中的mapcat只适用于序列,而Scala中的flatMap更灵活。

我的问题是,Clojure中的mapcat和Scala中的flatMap在操作方面有什么区别?

假设:

  • 我知道Scala有一个丰富的类型系统,Clojure有可选的类型——我很想知道mapcat接受的参数是否有限制,使它只具有flatMap的一个子集功能

我对Scala略知一二,但在我看来flatMap是monad中的Scala绑定函数,mapcat是Clojure中序列monad的绑定函数的可能实现。所以它们对于序列是一样的。

但Scala有一个用于Futures的flatMap函数:它接受一个future和一个映射函数,并返回一个在输入future完成后将完成的future。这个操作在Clojure中似乎不是一个简单的mapcat。它可以通过这种方式实现,而不是

(defn flat-map [f mv] (mapcat (fn [v] (future (f @v))) mv))

所以,不。它们不一样,操作内容也不一样。在Scala中,flatMap是不同函数的通用名称,例如Futures的flatMap协调输入和输出期货。Clojure中的简单mapcat不起作用,因为它不会返回未来。

它们看起来非常相似,似乎在处理相同的事情。通过查看文档和示例,我看不出功能上的差异。

mapcat处理序列,几乎每个clojure数据类型都可以是一个序列。如果您将尚未是seq的内容传递给mapcat,它将自动对其调用seq,因此在实践中,您可以将几乎所有clojure值传递给mapcat。如果要在树上进行迭代,则需要调用prewalkpostwalk来指定遍历顺序。

在标准Scala库中:ResponderFutureParserControlContext。它们都不是序列或特别像序列。CCD_ 17也有轻微变化。

真正的区别是flatMap在类型上是多态的,而mapcat不是。因此,任何类型都可以决定提供类似"flatMap"的行为。这就是为什么像Futures这样的东西是可平面映射的。

在Clojure中,mapcat是特定于seqable类型的。任何seqable都可以被强制为一个序列,并且所有序列都可以被映射和连接。mapcat实现将检查输入是否是seqable,如果是,它将对其调用seq以将其强制为序列,然后它将映射并cat该序列,并返回一个序列。您无法返回原始类型的结果。

在Scala中,如果你实现了IterableLike特性(我认为这是正确的接口),你就会得到默认的flatMap实现,它有点像Clojure实现,减去了对序列的强制。但是,许多类型还提供了flatMap的自定义实现,使其具有通用性。

最新更新