【发布时间】:2014-01-31 04:33:27
【问题描述】:
为什么foldLeft会被占用
f: (B, A) => B
和 foldRight 取
f: (A, B) => B
foldLeft 本来可以写成 f: (A, B) => B.
我试图理解参数顺序不同的原因。
【问题讨论】:
标签: scala
为什么foldLeft会被占用
f: (B, A) => B
和 foldRight 取
f: (A, B) => B
foldLeft 本来可以写成 f: (A, B) => B.
我试图理解参数顺序不同的原因。
【问题讨论】:
标签: scala
它应该向您显示聚合的方向。 FoldLeft 从左到右聚合,所以你可以想象累加器 B 在接近每个 A 时将左侧的东西聚在一起:
如果你有类似的东西:
Vector(1,2,3,4,5).foldLeft(0)((b,a) => b + a)
然后你会得到这种行为
B ...As...
---------------
(0), 1, 2, 3, 4, 5
(0+1), 2, 3, 4, 5
(0+1+2), 3, 4, 5
(0+1+2+3), 4, 5
(0+1+2+3+4), 5
(0+1+2+3+4+5)
另一方面,FoldRight 从右侧聚合事物。所以如果你有类似的东西:
Vector(1,2,3,4,5).foldRight(0)((a,b) => a + b)
然后你会得到这种行为
...As... B
-----------------
1, 2, 3, 4, 5 (0)
1, 2, 3, 4, (5+0)
1, 2, 3, (4+5+0)
1, 2, (3+4+5+0)
1, (2+3+4+5+0)
(1+2+3+4+5+0)
【讨论】:
@dhg 已经提供了一个很好的答案。我的例子说明了一个有趣的微妙之处:即,有时最初的顺序 值被传递给给定的函数事项。所以我想我会在有机会的时候发布这个 对 foldRight 的行为与 foldLeft 不同的情况感兴趣 具有相同的初始值、相同的函数和相同的输入列表。
考虑下面的幂运算:
def verbosePower(base:Double, exp:Double) = {
println(s"base=$base / exp=$exp") ;
math.pow(base, exp)
}
var X = List(2.0,3).foldLeft(1.0) (verbosePower)
System.out.println("x:" + X);
X = List(2.0,3).foldRight(1.0) (verbosePower)
System.out.println("x:" + X);
foldLeft 的输出和结果是:
base=1.0 / exp=2.0
base=1.0 / exp=3.0
X: Double = 1.0
foldRight 的输出和结果是:
base=3.0 / exp=1.0
base=2.0 / exp=3.0
X: Double = 8.0
【讨论】:
pow,foldLeft和foldRight是不同的。并且reduce(verbosePower) 调用并行收集也不会给出稳定的结果。