假设我有一个像这样的简单类
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中的值StringCanBuildFrom类型=> scala.collection.generic.CanBuildFrom [String,Char,String]和方法$ conforms in object Predef of type [A] => <:< [A,A]匹配预期类型A
如果我在调用f()
时添加类型信息,则会编译:
val f2: Int = f[Int]()
首先我遇到了隐式排序的情况,我认为它与Scala从左到右推断有关;我认为它不能首先匹配返回类型,然后然后推断f
的(隐式)参数类型。但后来我尝试了没有隐式排序的情况,看到它有效 - 它推断f
必须由Int
参数化,因为返回类型必须是Int
(因为{{1}是f2
)。
请注意,如果我们删除Int
并仅保留Ordering隐含参数,则错误仍然存在,但会变为
在对象排序中从方法Tuple9开始,为类型排序[A]分散隐式扩展。
再次添加类型参数,使其变为implicit a: A
有帮助。
发生了什么事?为什么编译器可以推断参数val f2: Int = f[Int]()
必须是A
,但参数Int
必须不是Ordering[A]
?
答案 0 :(得分: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()
}