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

7

假设我有一个简单的类如下:

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()

在编译过程中出现以下错误:

模糊的隐式值:对象 Predef 中类型为 => scala.collection.generic.CanBuildFrom [String,Char,String] 的值 StringCanBuildFrom 和类型为 [A] => <:<[A,A] 的方法 $conforms 都与预期的类型 A 匹配

如果在调用 f() 时添加类型信息,则可编译通过:

val f2: Int = f[Int]()

首先,我遇到了隐式排序的情况,我认为这与Scala从左到右推断有关;我认为它无法首先匹配返回类型,然后再推断f的(隐式)参数类型。但是后来我尝试了没有隐式排序的情况,发现它可以工作-它推断出f必须由Int进行参数化,因为返回类型必须是一个Int(因为f2是一个Int)。
需要注意的是,如果我们移除implicit a:A并仅留下Ordering隐式参数,则错误仍然存在,但变成了“Diverging implicit expansion for type Ordering [A] starting with method Tuple9 in object Ordering.”
同样地,添加类型参数使其变成val f2:Int = f[Int]()可以帮助解决问题。
发生了什么?为什么编译器可以推断参数A必须是一个Int,但不能推断参数Ordering [A]必须是一个Ordering [Int]
1个回答

1

生成实例的排序方式可能存在问题,因为下面的代码可以正常工作。我会报告一个错误。

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

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接