在集合上使用 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)
所以你得到四个 10
和 15
使得 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
。
我有这个奇怪的偏音演示。这是代码:
首先声明一个向量和一个部分。正如预期的那样,减少并应用向量 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)
所以你得到四个 10
和 15
使得 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
。