Why does this code raise a type mismatch error in Scala 2.9.2? I expected that getOrElse returns type String but actually it returns java.io.Serializable:
scala> implicit def StringToOption(s:String) = Option(s)
StringToOption: (s: String)Option[String]
scala> "a".getOrElse("")
res0: String = a
scala> var opt:Option[String] = "a".getOrElse("")
<console>:8: error: type mismatch;
found : java.io.Serializable
required: Option[String]
var opt:Option[String] = "a".getOrElse("")
^
This is OK:
scala> implicit def StringToOption(s:String): Option[String] = Option(s)
StringToOption: (s: String)Option[String]
scala> var b:Option[String] = "a".getOrElse("") toString
b: Option[String] = Some(a)
It’s an unwanted case of incomplete tree traversal. The signature of
getOrElseallows type widening, so when it realizes thatStringis notOption[String]it first tries to fill in a different type ascription ongetOrElse, i.e.Serializable. But now it has"a".getOrElse[Serializable]("")and it’s stuck–it doesn’t realize, I guess, that the problem was making the type too general before checking for implicits.Once you realize the problem, there’s a fix:
Now the typer doesn’t wander down the let’s-widen path, and finds the implicit.