就操作而言,Clojure中的mapcat和Scala中的flatMap有什么区别?

What are the differences between mapcat in Clojure and flatMap in Scala in terms of what they operate on?

我了解Scala中flatMap的等效项是Clojure中的mapcat

我有种种暗示,clojure中的mapcat仅适用于序列,而Scala中的flatMap更灵活。

我的问题是-Clojure中的mapcat和Scala中的flatMap之间的区别是什么?

假设:

  • 我知道Scala具有丰富的类型系统,而Clojure具有可选的类型-我想知道mapcat接受的参数是否受限制,从而使其仅具有flatMap s功能的子集。


我对Scala有点了解,但在我看来,flatMap是monad中的Scala绑定函数,而mapcat是Clojure中序列monad的bind函数的可能实现。因此,它们对于序列是相同的。

但是,例如,Scala具有Futures的flatMap函数:它接受一个Future和一个映射函数,并返回一个Future,该Future将在输入Future完成后完成。在Clojure中,此操作似乎不是简单的地图猫。可以这样实现

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

所以不行。它们的作用不同,也不相同。在Scala中,flatMap是不同功能的通用名称,例如Futures的flatMap协调输入和输出期货。 Clojure中的简单mapcat无法使用,因为它不会返回未来。


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


它们看起来非常相似,并且似乎在相同的事物上工作。通过查看文档和示例,我看不到功能上的差异。

mapcat适用于序列,几乎每种clojure数据类型都可以是序列。如果将尚未为seq传递给mapcat的东西传递给它,它将自动对其调用seq,因此实际上,您可以将几乎所有clojure值传递给mapcat。如果要遍历树,则需要调用prewalkpostwalk以指定遍历顺序。


真正的区别是flatMap在类型上是多态的,而mapcat不是。因此,任何类型都可以决定提供类似行为的" flatMap"。这就是您获得诸如Futureflatableable之类的东西的方式。

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

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