I am not sure what is the difference between fold
and foldLeft
in Scala.
The question Difference between fold and foldLeft or foldRight? has an
As another answer points out, the fold
method is primarily there to support a parallel fold. You can see this as follows. First we can define a kind of wrapper for integers that allows us to keep track of the operations that have been performed on its instances.
case class TrackInt(v: Int) {
val log = collection.mutable.Buffer.empty[Int]
def plus(that: TrackInt) = {
this.log += that.v
that.log += this.v
new TrackInt(this.v + that.v)
}
}
Next we can create a parallel collection of these things and an identity element:
val xs = (1 to 10).map(TrackInt(_)).par
val zero = TrackInt(0)
First we'll try foldLeft
:
scala> xs.foldLeft(zero)(_ plus _)
res0: TrackInt = TrackInt(55)
scala> zero.log
res1: scala.collection.mutable.Buffer[Int] = ArrayBuffer(1)
So our zero value is only used once, as we'd expect, since foldLeft
performs a sequential fold. Next we can clear the log and try fold
:
scala> zero.log.clear()
scala> xs.fold(zero)(_ plus _)
res2: TrackInt = TrackInt(55)
scala> zero.log
res3: scala.collection.mutable.Buffer[Int] = ArrayBuffer(1, 6, 2, 7, 8)
So we can see that the fold has been parallelized in such a way that the zero value is used multiple times. If we ran this again we'd be likely to see different values in the log.