scalahigher-order-functions

Scala: How to interpret foldLeft


I have two examples of foldLeft that I cannot really grasp the logic.

First example:

val donuts: List[String] = List("Plain", "Strawberry", "Glazed")
println(donuts.foldLeft("")((acc, curr) =>  s" $acc, $curr Donut ")) // acc for accumulated, curr for current

This will give

 , Plain Donut , Strawberry Donut , Glazed Donut

Does not foldLeft accumulate value that was earlier? I was expecting the result to be

 , Plain Donut ,  Plain Strawberry Donut , Strawberry Glazed Donut

Second example:

def multi(num:Int,num1:Int):Int=num*10

(1 until 3).foldLeft(1)(multi)

Can someone explain what is happening in every step? I cannot see how this can become 100. Also, the second argument multi is a function. Why does it not take any input variables (num and num1)?


Solution

  • Does not foldLeft accumulate value that was earlier?

    yes it does. It uses result of previous iteration and current element and produces new result (using the binary operator you have provided) so for the first example next steps are happening:

    1. the start value of accumulator - ""

    2. acc = "", curr = "Plain" -> " , Plain Donut "

    3. acc = " , Plain Donut ", curr = "Strawberry" -> " , Plain Donut , Strawberry Donut "

    4. acc = " , Plain Donut , Strawberry Donut ", curr = "Glazed" -> " , Plain Donut , Strawberry Donut , Glazed Donut "

    For the second example current value is simply ignored - i.e. multi can be rewritten as def multi(acc:Int, curr:Int):Int = acc*10 where curr is not actually used so foldLeft simply multiplies starting value (1) by 10 n times where n is number of elements in the sequence (i.e. (1 until 3).length which is 2).

    Why does it not take any input variables (num and num1)?

    foldLeft is a function which accepts a function. It accepts a generic function which in turn accepts two parameters and returns result of the same type as the first parameter (op: (B, A) => B, where B is the the result type and A is sequence element type). multi matches this definition when B == A == Int and is passed to the foldLeft which will internally provide the input variables on the each step.