"flatMap"这个词是从哪里来的?

Where does the word "flatMap" originate from?

如今,flatMap 是对类似 monad 的对象进行相应操作的最广泛使用的名称。 但是我找不到它第一次出现在什么地方,又是如何普及的。

我所知道的最古老的出现是在 Scala 中。 在 Haskell 中它被称为 bind。 在范畴论中使用希腊符号。

部分答案,希望能提供一些有用的 "seed nodes" 以开始更彻底的搜索。我的最佳猜测:

  • 1958 for map 用于列表处理,
  • 1988 用于 flatten 用于 monads 的上下文,
  • 2004 年 flatMap 在 Scala 中用作支持 for 理解的重要方法。

函数/方法名flatMap好像是flatten和map的合成词。这是有道理的,因为每当 M 是一些 monad,AB 是一些类型,而 a: M[A]f: A => M[B] 是一个值和一个函数,那么实现mapflatMapflatten 应该满足

a.flatMap(f) = a.map(f).flatten

(在 Scala 语法中)。

让我们首先分别考虑 mapflatten 这两个组件。

地图

map-函数似乎自古以来就被用来映射列表。我最好的猜测是它来自 Lisp(大约 1958 年),然后传播到所有其他具有类似高阶函数的语言。

展平

考虑到 Lisp 中列表表示的内容有多少,我假设 flatten 也被用于列表处理。

flatten 在 monad 上下文中的使用一定是最近的事情,因为 monad 本身在编程中引入的时间很晚。如果我们正在寻找单词 "flatten" 在单子计算上下文中的用法,我们可能至少应该查看 Eugenio Moggi 的论文。事实上,在 1988 年的 "Computational Lambda-Calculus and Monads" 中,他使用了公式:

Remark 2.2: Intuitively eta_A: A -> TA gives the inclusion of values into computations, while mu_A: T^2 A -> TA flatten a computation of a computation into a computation.

(排版是我改的,重点是我的,斜体字和原文一样)。我认为 Moggi 谈论扁平化 计算 而不仅仅是列表很有趣。

数学符号/"Greek"

关于数学符号中使用的希腊语:在范畴论中,比较常见的引入单子的方式是通过pureflatten对应的自然变换,[=对应的态射13=] 不再强调。然而,没有人称它为"flatten"。比如Maclane把方法pure对应的自然变换称为"unit"(不要和方法unit混淆),而flatten通常叫做"multiplication",类似于幺半群。当"triple"-术语更普遍时,人们可能会进一步调查它是否不同。

flatMap

要找到 flatMap 混成词的起源,我建议从今天最著名的流行词开始,然后尝试从那里回溯。显然,flatMap is a Scala meme,所以从 Scala 开始似乎是合理的。人们可能会检查通常怀疑的标准库(尤其是 List 数据结构):影响 Scala 的语言。这些 "roots" 在 Odersky 的 "Programming in Scala":

的第 1 章第 1.4 节中命名
  • C、C++ 和 C# 可能不是它的来源。
  • 在 Java 中是相反的:flatMap 来自 Scala 到 Java 的 1.8 版。
  • 关于 Smalltalk 我无话可说
  • Ruby肯定是has flat_mapEnumerable,但是我对Ruby一无所知,也不想深究源码了解它的推出时间。
  • Algol 和 Simula:绝对不是。
  • 够奇怪的ML(SML)seems to get by without flatMap, it only has concat (which is essentially the same as flatten). OCaml's lists also seem to have flatten, but no flatMap.
  • 正如你已经提到的,Haskell很久以前就有了这一切,但在Haskell中它被称为bind并写成运算符
  • Erlang has flatmap on lists,但我不确定这是起源,还是后来引入的。 Erlang 的问题是它是 1986 年的,那时候还没有 github.
  • 关于 Iswim、Beta 和 gbeta,我无话可说。

我认为可以公平地说 flatMap 已被 Scala 推广,原因有二:

  • flatMap 在 Scala 集合库的设计中发挥了重要作用,几年后它被证明可以很好地推广到大型分布式集合(Apache Spark 和类似工具)
  • flatMap 成为每个决定在 JVM 上正确进行函数式编程的人最喜欢的玩具(Scalaz 和受 Scalaz 启发的库,如 Scala Cats)

总结一下:"flatten" 术语从一开始就在 monad 的上下文中使用。后来,它与 map 合并为 flatMap,并被 Scala 推广,或者更具体地说,被 Apache Spark 和 Scalaz 等框架推广。

flatmap在第2.2.3节Sequences as Conventional Interfaces中被引入"Structure and Interpretation of Computer Programs" as

(define (flatmap proc seq)
  (accumulate append nil (map proc seq)))

该书的第一版于 1985 年出版。