简体   繁体   中英

Order of parameters to foldright and foldleft in scala

Why does the foldLeft take

f: (B, A) => B

and foldRight take

f: (A, B) => B

foldLeft could have been written to take f: (A, B) => B. I am trying to understand the reasoning for the difference in the order of parameters.

It's supposed to show you the direction of the aggregation. FoldLeft aggregates from left to right, so you can imagine the accumulator B as bunching up stuff on the left side as it approaches each A:

If you have something like:

Vector(1,2,3,4,5).foldLeft(0)((b,a) => b + a)

Then you get this behavior

 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, on the other hand, aggregates things from the right side. So if you have something like:

Vector(1,2,3,4,5).foldRight(0)((a,b) => a + b)

Then you get this behavior

  ...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 already provided a great answer. My example illustrates an interesting subtlety: namely, that sometimes the the order in which the initial value is passed to the given function matters. So I figured I'd post this on the off chance someone is interested in cases where foldRight can behave differently than foldLeft with the same initial value, same function, and same input list.

Consider the exponentiation below:

   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);

the output and result from foldLeft is:

base=1.0 / exp=2.0
base=1.0 / exp=3.0
X: Double = 1.0

the output and result from foldRight is:

base=3.0 / exp=1.0
base=2.0 / exp=3.0
X: Double = 8.0

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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