Scala for expressions: When to use "<-" and "="

Scala FAQ: When you write a Scala for expression or for loop, when do you use an = symbol and when do you use the <- symbol in the for block area?

Solution

In Scala's for expression, the <- symbol and the = symbol have distinct roles:

  1. The <- symbol: This is used to bind a value from a monadic expression — e.g., Option, List, Range, Future, ZIO, etc. — to a variable. It lets you extract values from these monadic types and use them within the for comprehension. (More on this in a moment.)

  2. The = symbol: This is used to define a local variable within the for comprehension. It can be used to perform intermediate computations that are not monadic operations.

Put another way, the <- symbol is used when you have a generator on the right side of the <-. As I’ve written in other tutorials and in the Scala Cookbook, generators in for expressions are things like lists, streams, ranges, etc.

for expression example using List, <-, and =

Here’s a complete example using a Scala List in the for expression:

val listExample: List[Int] = for {
    a   <- List(1, 2, 3)  // extract elements from the List
    b   <- List(4, 5, 6)  // extract elements from another List
    sum  = a + b          // define a local variable
} yield sum

println(listExample)  // Output: List(5, 6, 7, 6, 7, 8, 7, 8, 9, 6, 7, 8, 7, 8, 9, 8, 9, 10, 7, 8, 9, 8, 9, 10, 9, 10, 11)

for expression example using Option, <-, and =

To help drive the point home, here’s another example that uses Option values in a for expression:

val optionExample: Option[Int] = for {
    a   <- Some(10)   // extract the value from a Some
    b   <- Some(20)   // extract the value from another Some
    sum  = a + b      // define a local variable
} yield sum

println(optionExample)  // Output: Some(30)

val noneInt: Option[Int] = None
val noneExample: Option[Int] = for {
    a   <- Some(10)   // extract the value from a Some
    b   <- noneInt    // *attempt* to get a value from a None
    sum  = a + b      // note: this line will not be executed
} yield sum

println(noneExample)  // Output: None

Summary

In summary:

  • Use <- to extract and bind values from monadic expressions within a for comprehension. (Again, you can think of the value on the right side of the expression as being a generator.)
  • Use = to define local variables and perform non-monadic computations within a for comprehension.