Scala Language For Expressions Desugaring For Comprehensions


Example

for comprehensions in Scala are just syntactic sugar. These comprehensions are implemented using the withFilter, foreach, flatMap and map methods of their subject types. For this reason, only types that have these methods defined can be utilized in a for comprehension.

A for comprehension of the following form, with patterns pN, generators gN and conditions cN:

for(p0 <- x0 if g0; p1 <- g1 if c1) { ??? }

... will de-sugar to nested calls using withFilter and foreach:

g0.withFilter({ case p0 => c0  case _ => false }).foreach({
  case p0 => g1.withFilter({ case p1 => c1  case _ => false }).foreach({
    case p1 => ???
  })
})

Whereas a for/yield expression of the following form:

for(p0 <- g0 if c0; p1 <- g1 if c1) yield ???

... will de-sugar to nested calls using withFilter and either flatMap or map:

g0.withFilter({ case p0 => c0  case _ => false }).flatMap({
  case p0 => g1.withFilter({ case p1 => c1  case _ => false }).map({
    case p1 => ???
  })
})

(Note that map is used in the innermost comprehension, and flatMap is used in every outer comprehension.)

A for comprehension can be applied to any type implementing the methods required by the de-sugared representation. There are no restrictions on the return types of these methods, so long as they are composable.