从返回类型推断泛型隐式参数的类型



假设我有一个类似的简单类

abstract class Foo {
  implicit val impInt: Int = 42
  def f[A]()(implicit a: A): A
  val f2: Int = f()
}

当声明val f2时,编译器能够推断函数f的隐式参数的类型为Int,因为该类型与结果类型相同,并且结果类型需要与值f2的类型匹配,即Int

然而,将一个Ordering[A]放入混合物中:

def f[A]()(implicit a: A, m: Ordering[A]): A
val f2: Int = f()

导致此编译错误:

不明确的隐式值:类型=>scala.collection.generic.CanBuildFrom[String,Char,String]的对象Predef中的值StringCanBuildFrom和方法$都符合类型[A]=><的对象Preef:<[A,A]与预期的A类匹配

如果我在调用f()时添加类型信息,它会编译:

val f2: Int = f[Int]()

首先,我遇到了隐式排序的情况,我认为这与Scala从左到右的推理有关;我认为它无法首先匹配返回类型,然后推断f的(隐式)参数类型。但后来我尝试了没有隐式排序的情况,发现它是有效的——它推断f必须由Int参数化,因为返回类型必须是Int(因为f2Int)。

注意,如果我们删除implicit a: A并只保留Ordering隐式参数,则错误仍然存在,但变为

从对象Ordering中的方法Tuple9开始,类型Ordering[A]的发散隐式展开。

同样,添加类型参数使其成为val f2: Int = f[Int]()会有所帮助。

怎么回事?为什么编译器可以推断出参数A必须是Int,而不能推断出参数Ordering[A]必须是Ordering[Int]

正如下面的代码所示,生成排序实例的方式一定有问题。我会报告一个错误。

case object types {
  implicit def buh[X]: List[X] = List()
}
abstract class Foo {
  import types._
  def f[A]()(implicit l: List[A]): A
  val f2: Int = f()
}

相关内容

  • 没有找到相关文章

最新更新