在Clojure中的mapcat和Scala中的flatMap之间的区别是什么?

haw*_*eye 10 scala clojure

我理解flatMapScala中的等价物是mapcat在Clojure中.

我有一个暗示,mapcat在clojure只适用于序列,不像flatMapScala更灵活.

我的问题是 - 在他们的操作方面,mapcatClojure和flatMapScala 之间有什么区别?

假设:

  • 据我所知,Scala有一个丰富的类型系统,而Clojure有可选的输入 - 我很想知道mapcat接受的参数是否有限制,这使得它只有flatMaps功能的子集.

ica*_*mts 5

我对 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))
Run Code Online (Sandbox Code Playgroud)

所以不行。它们并不相同,无论是在操作什么方面。在 Scala 中, flatMap 是不同函数的通用名称,例如 Futures 的 flatMap 坐标输入和输出期货。Clojure 中的简单 mapcat 将不起作用,因为它不会返回未来。


Did*_* A. 1

真正的区别在于,flatMap 在类型上是多态的,而 mapcat 不是。因此任何类型都可以决定提供类似“flatMap”的行为。这就是你如何获得像 Futures 这样的东西是可扁平映射的。

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

在 Scala 中,如果您实现 IterableLike 特征(我认为这是正确的接口),您将获得默认的 flatMap 实现,它有点像 Clojure 的实现,只是减去了强制序列。但是,许多类型还提供了 flatMap 的自定义实现,使其以这种方式通用。