Clojure:map与comp有何不同?

5

map函数接受一个函数和一个列表,然后将该函数应用到列表中的每个元素。例如:

(map f [x1 x2 x3])
;= [(f x1) (f x2) (f x3)]

数学上,列表是自然数 ℕ 的部分函数。如果 x : ℕ → X 是某个列表,并且 f : XY 是某个函数,则 map 将对偶 (f, x) 映射为列表 f○x : ℕ → Y。因此,在简单情况下,map 和 comp 返回相同的值。

然而,当我们使用多个参数应用 map 时,会发生更复杂的情况。考虑以下示例:

(map f [x1 x2 x3] [y1 y2 y3])
;= [(f x1 y1) (f x2 y2) (f x3 y3)]

在这里,我们有两个列表 x:ℕ → Xy:ℕ → Y,具有相同的域,并且一种类型为 fX → (YZ) 的函数。为了在元组(fxy)上进行评估,map 必须在幕后进行更多工作。
首先,map 构造对角乘积列表 diag(xy):ℕ → X × Y,其中 diag(xy)(n)=(x(n),y(n))。
其次,map 对函数进行反柯里化操作 curry-1f):X × YZ。最后,map 将这些操作组合起来,以获得 curry-1(f)○diag(xy):ℕ → Z
我的问题是:这种模式是否可以推广?也就是说,假设我们有三个列表 x:ℕ → Xy:ℕ → Yz:ℕ → Z,以及一个函数 fX →(Y →(ZW))。map 是否将元组(fxyz)发送到列表 curry-2(f)○diag(xyz):ℕ → W
3个回答

6

看起来问题标题与实际问题的联系很小,我会试着解决这两个问题。

Clojure方面

正如(map inc [1 2 3])(comp inc [1 2 3])这样的示例所证明的那样 -- 顺便说一下,在Clojure中这两个示例都非常有意义 -- Clojure函数mapcomp即使在一个序列情况下也是完全不同的。 map并不像软件概念中的可调用对象一样将其序列参数作为函数处理,而comp则以此方式处理其所有参数; map返回复合数据,而comp则不返回任何值; comp返回的值可以作为函数进行调用,而map的返回值不能; 等等。

(其他类似的函数式语言也有单独的“map”和“compose”高阶函数; 在Haskell中,它们是map(以及更通用的fmap)和(.))。

值得注意的是,map不对其输入函数执行任何内存内部化参数操作,并且不对输入函数应用任何deschönfinkelizing / uncurrying变换。

数学方面

这个模式当然可以很好地推广,但值得记住的是,函数是什么以及它作用于哪个对象等等 -- 就像模型的内部一样 -- 取决于表示的选择,这种选择往往是任意的。有限序列可以完全表示为具有有限序数为定义域的(总)函数,或者作为Kuratowski元组,或者按照您描述的方式表示,其中您不在乎列表不一定是“gapless”等等。根据表示选择,自然数的概念可能根本不会出现在图片中,表示列表的对象可能看起来像函数,其值域是列表条目的超集,等等。


“deschönfinkelizing”是什么意思?您是指http://en.wikipedia.org/wiki/Moses_Sch%C3%B6nfinkel吗? - spike
@spike 与“uncurrying”相同;是的,名称指的是引入该概念的Schönfinkel。(不知道我是否应该拼成“deschönfinkeling”。) - Michał Marczyk

3

我不知道这是否有帮助,但:

  • Clojure没有像Haskell一样的柯里化。它确实有部分函数应用,但与柯里化不同。
  • Clojure的map更像Haskell中的zipWith、zipWith3等函数。

1

从技术上讲,可以将map视为像这样组成函数,但在实践中,它引入了一些comp没有的开销。

map产生一个惰性序列,在最终读取结果时计算序列。因此,它返回的是一个序列,而不是你的类型表达式所暗示的结果。它还增加了序列的开销,并改变了评估顺序,因为它是惰性和分块的。


“map” 简单地返回与 “comp” 不同的值,当它们都传递相同的参数时(这是在假设对于两者都有意义的一组参数的情况下,当然可能不是这种情况),所以我不知道说它引入了 comp 没有的开销是否公平。@MichielBorkent 在多层序列转换管道的不同层次上交错评估,在分块存在的情况下会发生变化。((filter odd? (map inc [1 2 3])) -> 所有增量操作在所有过滤操作之前执行;对于更长的向量,它们将被交错执行。) - Michał Marczyk

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接