Strange behavior in for
cycle pattern matching:
scala> val a = Seq(Some(1), None)
a: Seq[Option[Int]] = List(Some(1), None)
scala> for (Some(x) <- a) { println(x) }
1
scala> for (None <- a) { println("none") }
none
none
Why in second example two output 'none'
produced? Maybe this example is synthetic and not practical, but such behavior is not expectable. Is this bug or feature?
What do you know, it is a bug:
https://issues.scala-lang.org/browse/SI-9324
scala> val vs = Seq(Some(1), None)
vs: Seq[Option[Int]] = List(Some(1), None)
scala> for (n @ None <- vs) println(n)
None
The spec in umambiguous:
http://www.scala-lang.org/files/archive/spec/2.11/06-expressions.html#for-comprehensions-and-for-loops
Compare midstream assignment, which does not exhibit the bug:
scala> for (v <- vs; None = v) println(v)
scala.MatchError: Some(1) (of class scala.Some)
at $anonfun$1.apply(<console>:9)
at $anonfun$1.apply(<console>:9)
at scala.collection.TraversableLike$$anonfun$map$1.apply(TraversableLike.scala:245)
at scala.collection.TraversableLike$$anonfun$map$1.apply(TraversableLike.scala:245)
at scala.collection.immutable.List.foreach(List.scala:381)
at scala.collection.TraversableLike$class.map(TraversableLike.scala:245)
at scala.collection.immutable.List.map(List.scala:285)
... 33 elided
That's because None
was interpreted as a name of variable:
scala> for (None <- a) { println(None) }
Some(1)
None
Here is simplified example without for
:
scala> val None = 5
None: Int = 5
scala> val Some(a) = Some(5)
a: Int = 5