I understand for-expression is translated into map and flatMap. But I found something that I can not explain and need your helps. Here are two toy examples:
for {
None <- List(Option(1),None)
} yield 0
//res0: List[Int] = List(0, 0)
Q1: Why Some(1) is map to 0 ? I was expecting List(0),
update1:
thanks the comment of @marios , ths one is more bizarre.
for(None <- List(Some(1), None) ) yield None
returns List(Some(1), None)
.
update2:
some says it is a variable, but in IDE, it really links to a None
object.
I use IntelliJ to auto-translate the above for-expression to map-expression:
List(Option(1), None).map { case None => 0 }
//scala.MatchError: Some(1)
Q2: The error from this map-expression is expected, while the for-expression in first question doesn't give me this error. Why they get the different computation ?
This appears to be a bug in the Scala compiler. The Scala Language Specification states: "In a first step, every generator p <- e
, where p
is not irrefutable for the type of e
is replaced by p <- e.withFilter { case p => true; case _ => false }
", and then "a for comprehension for (p <- e) yield e′
is translated to e.map { case p => e′ }
."
This means your example, for { None <- List(Option(1), None) } yield 0
, should be translated to
List(Option(1),None).withFilter { case None => true; case _ => false }.map{case None => 0}
which evaluates to List(0)
, as you expected.