在集合上使用 partial,reduce -vs- apply

Using partial over a collection, reduce -vs- apply

我有这个奇怪的偏音演示。这是代码:

首先声明一个向量和一个部分。正如预期的那样,减少并应用向量 a:

上的整数求和
> (def a [1 2 3 4 5])
> (def p (partial + 10))
> (apply + a)
15
> (reduce + a)
15

现在,在局部 p 和矢量 a 上使用应用,我从局部得到 a+10 的总和,这使得意义:

> (apply p a)
25

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

> (reduce p a)
55

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

> (+ (first a) (reduce + (map #(+ % 10) (rest a))))
55

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

首先要注意的是 + 是可变的:它可以用零个、一个、两个或更多参数调用。当您执行 (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.

p上的reduce如上图是要重复调用的,但是这次函数每次都加上10(reduce p a) = (p (p (p (p 1 2) 3) 4) 5) = (+ 10 (+ 10 (+ 10 (+ 10 1 2) 3) 4) 5) 所以你得到四个 1015 使得 55.

另一种看待的方式:

给定

(def p (partial + 10))

然后 (p x y) 表示 (+ 10 x y),对于任何 x y

所以

(reduce p a)

表示

(reduce (fn [x  y] (+ 10  x  y)) a)

...因为 reduce 的第一个参数是两个参数的函数。

未提供初始值,因此 (first a) 被原样使用,缩减应用于 (rest a),它有四个元素。

  • a的所有元素被添加进来:第一个作为初始值; 其他的减少。
  • 10 在每个减少周期中被添加:四次。

所以最后的结果和

一样
(+ (* 10 (dec (count  a))) (reduce + a))

在这种情况下,55