在集合上使用部分,reduce -vs-apply

diz*_*tar 6 clojure

我有这个奇怪的部分演示。这是代码:

首先声明一个向量和一个部分。正如预期的那样, reduce 和 apply 对 vector 上的整数求和a

> (def a [1 2 3 4 5])
> (def p (partial + 10))
> (apply + a)
15
> (reduce + a)
15
Run Code Online (Sandbox Code Playgroud)

现在,使用上的部分应用p和载体a,我得到的总和a+10从局部的,这是有道理的:

> (apply p a)
25
Run Code Online (Sandbox Code Playgroud)

现在,使用(reduce)对我来说毫无意义。哪里55来的?

> (reduce p a)
55
Run Code Online (Sandbox Code Playgroud)

我能想到的最接近的是,(reduce)version 从 1 索引中添加 10 并在将所有内容添加在一起之前忽略零索引:

> (+ (first a) (reduce + (map #(+ % 10) (rest a))))
55
Run Code Online (Sandbox Code Playgroud)

我只是好奇是否有人确切地知道这里发生了什么?我真的不知道我期待什么答案,但我也不明白发生了什么。我不知道为什么我会得到55答案。

Sea*_*eld 12

首先要注意的+是可变参数:可以使用零、一个、两个或多个参数调用它。当你这样做时,(apply + a)你基本上是+用五个参数调用并取回总和 ( 15)。

但是,reduce将函数严格视为二进制并重复调用它,将前一次调用的结果作为下一次调用的第一个参数。(reduce + a)(+ (+ (+ (+ 1 2) 3) 4) 5)这也恰好是15

所以,你partial也可变参数,可以用五个参数调用,如apply调用:(apply p a)= (p 1 2 3 4 5)=(+ 10 1 2 3 4 5)等你拿25

reducep会如上图所示,但这次的函数将重复调用它10每次在:(reduce p a)= (p (p (p (p 1 2) 3) 4) 5)= (+ 10 (+ 10 (+ 10 (+ 10 1 2) 3) 4) 5),所以你得到四次10S和15决策55