Skip to content

Scala For Comprehensions

Basics

From chapter 60 of functional-programming-simplified:

// def makeInt(s: String): Option[Int]

val sum = for {
        a <- makeInt("1")
        b <- makeInt("2")
        c <- makeInt("3")
        d <- makeInt("4")
    } yield a + b + c + d

compiles to the following (intermediate result):

val sum = makeInt("1").flatMap(
  ((a) => makeInt("2").flatMap(
    ((b) => makeInt("3").flatMap(
      ((c) => makeInt("4").map(
      ((d) => a.$plus(b).$plus(c).$plus(d)))))
      )
    )
  )
);

ie, it's a series of flatMap calls followed by a single map call. This is how for expressions like this are converted by the Scala compiler.

Any class that implements map and flatMap can be used in a for expression in the same way that Option is used in the example above.

Examples

val allPairs = List(1, 2, 3).flatMap(number => List('a', 'b', 'c').map(letter => s"$number-$letter"))
println(allPairs)
// List(1-a, 1-b, 1-c, 2-a, 2-b, 2-c, 3-a, 3-b, 3-c)

// the above is equivalent to
val allPairsWithForComp = for {
  number <- List(1, 2, 3)
  letter <- List('a', 'b', 'c')
} yield s"$number-$letter"

println(allPairsWithForComp)
// List(1-a, 1-b, 1-c, 2-a, 2-b, 2-c, 3-a, 3-b, 3-c)