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 getOrElse
allows type widening, so when it realizes that String
is not Option[String]
it first tries to fill in a different type ascription on getOrElse
, 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:
"a".getOrElse[String]("")
Now the typer doesn't wander down the let's-widen path, and finds the implicit.