Scala类型推断和多个参数列表

时间:2017-02-11 12:01:24

标签: scala type-inference typechecking

(Scala 2.11.8)

请考虑以下代码:

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
  }
}

此处,行f1(123)(ord)会引发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)

如果我们将呼叫更改为f1[B](123)(ord),则错误消失。

为什么多个参数列表的存在会混淆typechecker?这是一个错误,还是一个预期的结果?

1 个答案:

答案 0 :(得分:4)

这不是错误 - 分离到参数列表意味着仅根据第一个参数列表推断出类型参数:

f1(123)(ord) 

可以改写为:

val partiallyApplied = f1(123)
partiallyApplied(ord)

现在 - partiallyApplied的类型是什么?由于类型参数未被明确设置,并且没有用于推理的参数/返回类型,因此类型参数被推断为A(没有具体的{{} 1}}!所以B的类型是partiallyApplied),因此在(Ordering[A]) => Int之后使用它会产生异常。

相反,在致电时:

Ordering[B]

由于f2(123, ord) 的类型为ord,因此可以将类型参数推断为Ordering[B],因此编译成功。