Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Behaviour of Options inside for comprehension is Scala

Two newbie questions.

It seems that for comprehension knows about Options and can skip automatically None and unwrap Some, e.g.

val x = Map("a" -> List(1,2,3), "b" -> List(4,5,6), "c" -> List(7,8,9))
val r = for {map_key <- List("WRONG_KEY", "a", "b", "c")
             map_value <- x get map_key } yield map_value

outputs:

r: List[List[Int]] = List(List(1, 2, 3), List(4, 5, 6), List(7, 8, 9))

Where do the Options go? Can someone please shed some light on how does this work? Can we always rely on this behaviour?

The second things is why this does not compile?

val x = Map("a" -> List(1,2,3), "b" -> List(4,5,6), "c" -> List(7,8,9))
val r = for {map_key <- List("WRONG_KEY", "a", "b", "c")
                 map_value <- x get map_key
                 list_value <- map_value
    } yield list_value

It gives

Error:(57, 26) type mismatch;
 found   : List[Int]
 required: Option[?]
             list_value <- map_value
                        ^

Looking at the type of the first example, I am not sure why we need to have an Option here?

like image 258
Alexey Kalmykov Avatar asked Jan 30 '26 21:01

Alexey Kalmykov


1 Answers

For comprehensions are converted into calls to sequence of map or flatMap calls. See here

Your for loop is equivalent to

List("WRONG_KEY", "a", "b", "c").flatMap(
  map_key => x.get(map_key).flatMap(map_value => map_value)
)

flatMap in Option is defined as

 @inline final def flatMap[B](f: A => Option[B]): Option[B]

So it is not allowed to pass List as argument as you are notified by compiler.

like image 102
Evgeny Avatar answered Feb 01 '26 13:02

Evgeny



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!