In the following session with scala 2.10.0-M7:
scala> trait A
defined trait A
scala> class B extends A
defined class B
scala> class C extends A
defined class C
scala> Some(0).fold(new B){_=>new C}
<console>:11: error: type mismatch;
found : C
required: B
Some(0).fold(new B){_=>new C}
I would expect the compiler find the common supertype (namely A) rather than complaining. Is it the general type inference limitation, or the consequence of the way Option.fold is defined?
Thank you.
The problem results of a combination of Scalas type inference algorithm and the way how Option.fold
is defined.
Scalas type inference works from left to right, this means that it starts with the leftmost symbol to search for a possible type for an expression. Further, for method parameter lists this means, that a generic type is bound to the type filled in by the leftmost parameter list:
scala> def meth[A](a1: A, a2: A) = (a1, a2)
meth: [A](a1: A, a2: A)(A, A)
scala> meth(1, "")
res7: (Any, Any) = (1,"")
scala> def meth[A](a1: A)(a2: A) = (a1, a2)
meth: [A](a1: A)(a2: A)(A, A)
scala> meth(1)("")
<console>:10: error: type mismatch;
found : String("")
required: Int
meth(1)("")
^
As one can see, in the first case Any
is inferred, whereas in the second case a compiler error is thrown because the type of A
is bound by the first parameter list and the second one can't change it any more.
But in order to get he method call in the question to work, the type of the resulting Option
may not defined until the second parameter list is reached. Because this requires a right to left type inference hence the error. This is somewhat identical to List.fold
:
scala> List(1).foldLeft(Nil)((xs,x) => x::xs)
<console>:8: error: type mismatch;
found : List[Int]
required: scala.collection.immutable.Nil.type
List(1).foldLeft(Nil)((xs,x) => x::xs)
^
To get the code to work one has to explicitly specify the type of the resulting collection, see @rks answer for an example.
See the discussion here for the full explanation why it is defined as it is defined. In short: Option
follows the design of collections in a lot of respects - thus it is more clear when it behaves the same way as collections do.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With