爲什麼foldLeft
採取秩序參數foldright和斯卡拉foldleft
f: (B, A) => B
和foldRight採取
f: (A, B) => B
foldLeft
可能已被寫入採取f: (A, B) => B.
我試圖理解推理爲參數的順序的差異。
爲什麼foldLeft
採取秩序參數foldright和斯卡拉foldleft
f: (B, A) => B
和foldRight採取
f: (A, B) => B
foldLeft
可能已被寫入採取f: (A, B) => B.
我試圖理解推理爲參數的順序的差異。
它應該顯示聚合的方向。 FoldLeft彙總來自左到右,所以你可以想像蓄電池B中左側聚成一團的東西,因爲它接近各個答:
如果你有這樣的:
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)'也不會產生穩定的結果。 – dk14
@ dk14關於發生了什麼事情的很好的數學總結。 –