Clojure:地图与comp有什么不同?

时间:2013-09-17 18:08:15

标签: list math map clojure

map接受一个函数和一个列表,并将该函数应用于列表的每个元素。如,

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

数学上,列表是自然数ℕ的部分函数。如果 x :ℕ→ X 是某个列表, f X Y 是某个函数,然后map将对( f x )带到列表f○x:ℕ→ Y 。因此,map和comp返回相同的值,至少在简单的情况下。

然而,当我们应用具有多个参数的地图时,会发生更复杂的事情。考虑一下这个例子:

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

在这里,我们有两个列表 x :ℕ→ X y :ℕ→ Y 相同的域,以及 f 类型的函数: X →( Y Z )。为了评估元组( f x y ),地图必须在幕后做更多的工作。

首先,map构造对角线产品列表diag( x y ):ℕ→ X × Y ,由diag定义( x y )(n)=( x (n), y (N))。

其次,地图不会影响咖喱 -1 f ): X × Y →< EM>ž。最后,map组成这些操作以获得curry -1 (f)○diag( x y ):ℕ→ Z < / em>的

我的问题是:这种模式是否概括?也就是说,假设我们有三个列表 x :ℕ→ X y :ℕ→ Y z :ℕ→ Z ,函数 f X →( Y →( Z W )))。 map是否将元组( f x y z )发送到列表curry - 2 (f)○diag( x y z ):ℕ→ W

3 个答案:

答案 0 :(得分: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元组,或者你描述的方式,你不关心你的列表不一定是“无间隙”等等。取决于表示选择,自然数的概念可能根本不会进入图片,表示列表的对象可能看起来像或者看起来不像其codomain是列表条目集等的超集的函数。

答案 1 :(得分:3)

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

  • Clojure没有像Haskell那样的人。它确实有部分功能应用,但它与currying不同。
  • Clojure的地图更像是Haskell中的zipWith,zipWith3等

答案 2 :(得分:1)

技术上是的,map可以被视为这样的组合函数,尽管在实践中它引入了一些comp没有的开销。

map生成一个延迟序列,在最终读取结果时将计算序列。所以它返回的序列不是严格意义上的类型表达式所暗示的结果。它还增加了序列的开销并改变了评估顺序,因为它是懒惰和分块的。