“flatMap”一词从何而来?

Where does the word "flatMap" originate from?

提问人:simpadjo 提问时间:4/15/2018 最后编辑:Andrey Tyukinsimpadjo 更新时间:4/22/2020 访问量:2374

问:

现在,flatMap 是使用最广泛的名称,用于对类 monad 对象进行相应的操作。 但我找不到它第一次出现在哪里,是什么普及了它。

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

函数式编程 语言无关的 monads 术语 历史记录

评论

4赞 sepp2k 4/15/2018
列表版本在 Haskell 中被调用,因为它是 .在 Scala 中(除其他外)被称为 ,所以是有道理的。concatMapconcat . mapconcatflattenflatMap
1赞 simpadjo 4/15/2018
@sepp2k感谢您的回复。我理解这个词的含义。我对这里的历史概述很感兴趣。
1赞 Sylwester 4/15/2018
如果替换为,则会返回列表列表。如果结果是,则从 . 存在于 60 年代的 Lisp 中,并在 58 的原始 lisp 论文中存在变体。在 CL 中,CLHS 将其解释为 。因此,在名称中使用 or 只是表示用户对将列表视为数据或参数的看法。flatMapmapflattenflatMapmapmaplistflatMapmapcan(apply #'nconc (mapcar f x1 ... xn))flattenconcat
0赞 Will Ness 12/19/2018
@Sylwester在一个不相关的切线上,我曾经尝试过.你能在不尝试的情况下分辨出它的作用吗?/只是为了好玩/(mapcon #'(lambda (x) x) (list 1 2 3))
0赞 Sylwester 12/19/2018
@WillNess 在第一次迭代之后,在第二次迭代之后,它会停留一段时间,同时它试图到达最后一对以应用下一个:-p顺便说一句,我想我说得有点快,因为本质上可能没有破坏性。(1 2 3)(1 . #1=(2 3 . #1#))mapcanflatMapflatMap

答:

10赞 Andrey Tyukin 4/16/2018 #1

部分答案,希望能提供一些有用的“种子节点”来开始更彻底的搜索。我最好的猜测:

  • 1958年用于列表处理,map
  • 1988 年用于单子的上下文,flatten
  • 2004 年被用作 Scala 中的重要方法支持推导式。flatMapfor

函数/方法名称似乎是一个合成词,由扁平十和 map 组成。这是有道理的,因为每当是一些 monad、、一些类型和 、 一个值和一个函数,那么 的实现 和 应该满足flatMapMABa: M[A]f: A => M[B]mapflatMapflatten

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

(在 Scala 语法中)。

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

地图

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

扁平 化

考虑到 Lisp 中有多少东西是由列表表示的,我认为它也被用于列表处理。flatten

in context of monads 的使用一定是最近才出现的,因为 monads 本身在编程中被引入的时间要晚得多。如果我们在一元计算的上下文中寻找“扁平化”一词的用法,我们可能至少应该检查一下 Eugenio Moggi 的论文。事实上,在 1988 年的“Computational Lambda-Calculus and Monads”中,他使用了以下公式:flatten

备注 2.2:直观地将值包含在计算中,同时将计算的计算扁平化计算eta_A: A -> TAmu_A: T^2 A -> TA

(排版由我更改,强调我的,文本为斜体和原文一样)。我认为有趣的是,Moggi 谈论的是扁平化计算,而不仅仅是列表。

数学符号 / “希腊语”

关于数学符号中使用的希腊语:在范畴论中,引入单子的更常见的方法是通过对应于 和 的自然变换,对应的形态被去强调。然而,没有人称其为“扁平化”。例如,Maclane 将对应于方法的自然变换称为“unit”(不要与方法 unit 混淆),通常称为“乘法”,类似于 Monoids。人们可能会进一步调查,当“三重”术语更普遍时,情况是否不同。pureflattenflatMappureflatten

平面地图

为了找到 portmanteau 这个词的起源,我建议从今天最杰出的普及者开始,然后尝试从那里回溯。显然,flatMap 是一个 Scala 模因,所以从 Scala 开始似乎是合理的。人们可能会检查通常可疑的标准库(尤其是数据结构):影响 Scala 的语言。这些“根”在 Odersky 的“Programming in Scala”的第 1 章第 1.4 节中被命名:flatMapList

  • C,C++和C#可能不是它的来源。
  • 在 Java 中,情况正好相反:它来自 Scala 的 Java 1.8 版本。flatMap
  • 关于Smalltalk,我什么也说不出来
  • Ruby 肯定flat_map,但我对 Ruby 一无所知,我不想深入研究源代码来了解它是什么时候引入的。Enumerable
  • Algol 和 Simula:当然不是。
  • 奇怪的是,ML (SML) 似乎在没有 flatMap 的情况下也能过得去,它只有(这与 .OCaml 的列表似乎也有扁平化,但没有 flatMapconcatflatten
  • 正如你已经提到的,Haskell很久以前就有了这一切,但在Haskell中,它被调用和编写为运算符bind
  • Erlang 在列表中有平面地图,但我不确定这是起源,还是后来引入的。Erlang 的问题在于它是从 1986 年开始的,当时还没有 github。
  • 我不能说任何关于 Iswim、Beta 和 gbeta 的事情。

我认为可以公平地说,Scala 已经普及了它,原因有两个:flatMap

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

总而言之:“扁平化”术语从一开始就被用于单子的上下文中。后来,它与 into 结合,并被 Scala 推广,或者更具体地说,被 Apache Spark 和 Scalaz 等框架推广。mapflatMap

评论

1赞 D. Ben Knoble 4/22/2020
只是在阅读...SML 有List.concat : 'a list list -> 'a list
0赞 Andrey Tyukin 4/22/2020
谢谢@D.BenKnoble,已修复。
6赞 Grisha 10/21/2019 #2

flatmap在第 2.2.3 节 序列作为“计算机程序的结构和解释”中的常规接口中介绍为

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

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

评论

2赞 Will Ness 10/21/2019
正如书中所指出的,“David Turner 向 [SICP 的作者] 展示了这种嵌套映射的方法,他的语言 KRC 和 Miranda 为处理这些结构提供了优雅的形式主义。本节中的示例(另见练习 2.42)改编自 Turner 1981。这是1981年KRC的一篇论文
2赞 Will Ness 10/22/2019
(续)谈到使用嵌套生成器解决“ZF 表达式”(即列表推导式)的回溯问题——这意味着 ping。concatMap