从 return 类型推断通用隐式参数的类型
Inferring type of generic implicit parameter from return type
假设我有一个像这样的简单 class
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()
导致此编译错误:
Ambiguous implicit values: both value StringCanBuildFrom in object Predef of type => scala.collection.generic.CanBuildFrom[String,Char,String] and method $conforms in object Predef of type [A]=> <:<[A,A] match expected type A
如果我在调用 f()
时添加类型信息,它会编译:
val f2: Int = f[Int]()
首先我遇到了隐式排序的情况,我认为这与 Scala 从左到右推断有关;我认为它无法先匹配 return 类型,然后 然后 推断 f
的(隐式)参数类型。但后来我在没有隐式排序的情况下尝试了这种情况,发现它有效 - 它推断 f
必须由 Int
参数化,因为 return 类型必须是 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]
?
排序实例的生成方式肯定有问题,因为下面的代码有效。我会报告错误。
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()
}
假设我有一个像这样的简单 class
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()
导致此编译错误:
Ambiguous implicit values: both value StringCanBuildFrom in object Predef of type => scala.collection.generic.CanBuildFrom[String,Char,String] and method $conforms in object Predef of type [A]=> <:<[A,A] match expected type A
如果我在调用 f()
时添加类型信息,它会编译:
val f2: Int = f[Int]()
首先我遇到了隐式排序的情况,我认为这与 Scala 从左到右推断有关;我认为它无法先匹配 return 类型,然后 然后 推断 f
的(隐式)参数类型。但后来我在没有隐式排序的情况下尝试了这种情况,发现它有效 - 它推断 f
必须由 Int
参数化,因为 return 类型必须是 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]
?
排序实例的生成方式肯定有问题,因为下面的代码有效。我会报告错误。
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()
}