繁体   English   中英

在scala中折叠和折叠的参数顺序

[英]Order of parameters to foldright and foldleft in scala

为什么foldLeft需要

f: (B, A) => B

和foldRight采取

f: (A, B) => B

foldLeft本来可以写成f: (A, B) => B.我试图理解参数顺序差异的推理。

它应该向您展示聚合的方向。 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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM