Gary Sieling

Scala foldRight example

The foldLeft, foldRight, and reduce functions let you combine a bunch of values into one. You might infer, correctly, from the names that foldLeft and foldRight iterate over a list in opposite directions.

Interestingly, not only do these traverse the list in opposite directions, the arguments to your combiner function are flipped:

val myList = List(1, 2, 3)

myList.
  zipWithIndex.
  foldRight("start: ")( 
    (data, y) => y + " " + (data._1 * data._2).toString
  )

res123: String = start:  6 2 0

myList.
  zipWithIndex.
  foldLeft("start: ")( 
    (y, data) => y + " " + (data._1 * data._2).toString
  )

res120: String = start:  0 2 6

Unfortunately Scala differs from Javascript in a key way here, in that you need the “.” to be at the end of each line, or Scala is unable to tell that the statement continues to the next line. If you don’t do this, you will get a ton of errors:

scala>   .zipWithIndex
:1: error: illegal start of definition
         .zipWithIndex

Note also that according to the documentation, foldRight is implemented as so (with “op” being your combiner function):

foldRight = op(x_1, op(x_2, ... op(x_n, z)...))

foldLeft = op(...op(z, x_1), x_2, ..., x_n)

With this in mind, it definitely will not complete on infinite lists. Ideally this uses tail call recursion internally, so it may effectively behave the same as a regular loop. An interesting consequence of this implementation (over a loop) is that the recursive implementations should likely work well regardless of whether you can get the i-th item in the list quickly (i.e. a forward linked list have about the same performance characteristics with foldLeft and foldRight, if they use recursion).

Exit mobile version