Scala type inference and multiple arguments list
(Scala 2.11.8)
Consider the following code:
trait Class[A] {
def f1[B >: A](arg1: Int)(ord: Ordering[B]): Int
def f2[B >: A](arg1: Int, ord: Ordering[B]): Int
def f[B >: A](ord: Ordering[B]): Int = {
f1(123)(ord) // Compilation error!
f2(123, ord) // OK
}
}
Here, line f1(123)(ord)
raises type mismatch; found : Ordering[B] required: Ordering[A] Note: B >: A, but trait Ordering is invariant in type T. You may wish to investigate a wildcard type such as _ >: A. (SLS 3.2.10)
type mismatch; found : Ordering[B] required: Ordering[A] Note: B >: A, but trait Ordering is invariant in type T. You may wish to investigate a wildcard type such as _ >: A. (SLS 3.2.10)
If we change the call to f1[B](123)(ord)
, error disappears.
Why does the presence of multiple arguments list confuses the typechecker? Is this a bug, or an expected result?
It's not a bug - the separation into parameter lists means that the type parameter is inferred based on the first argument list alone:
f1(123)(ord)
can be rewritten as:
val partiallyApplied = f1(123)
partiallyApplied(ord)
Now - what is partiallyApplied
's type? Since the type parameter wasn't explicitly set, and there's no argument / return type to use for inference, the type parametter is inferred to be A
(there's no specific B
yet! So partiallyApplied
's type is (Ordering[A]) => Int
), hence using it with Ordering[B]
later gives the exception.
In contrast, when calling:
f2(123, ord)
Since ord
has type Ordering[B]
, the type parameter can be inferred to be B
, hence compilation succeeds.
上一篇: Scala编译器不能正确推断类型
下一篇: Scala类型推断和多个参数列表