从返回类型推断通用隐式参数的类型 [英] Inferring type of generic implicit parameter from return type
问题描述
说我有一个像这样的简单班级
Say I have a simple class like this
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
.
When declaring val f2
, compiler is able to infer that the type of implicit parameter of function f
is Int
because that type is the same as the result type, and result type needs to match the type of value f2
, which is 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在类型为[A] =>的对象Predef中. [A,A]匹配预期的类型A
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()
时添加类型信息,它将编译:
If I add the type information when invoking f()
, it compiles:
val f2: Int = f[Int]()
首先,我遇到了隐式排序的情况,我认为这与Scala从左到右进行推断有关;我认为它不能首先匹配返回类型,然后然后推断f
的(隐式)参数类型.但是后来我尝试了这种情况,没有隐式排序,并且看到了它的工作原理-推断f
必须由Int
参数化,因为返回类型必须为Int
(因为f2
是Int
) .
First I encountered the case with implicit ordering and I thought it has to do with Scala inferring left-to-right; I thought it's not able to match the return type first and then infer the (implicit) parameter type of f
. But then I tried the case without implicit ordering and saw that it works - it inferred that f
must be parameterized by Int
because the return type has to be an Int
(because f2
is an Int
).
请注意,如果我们删除implicit a: A
并仅保留Ordering隐式参数,则错误仍然存在,但变为
Note that if we remove implicit a: A
and leave only the Ordering implicit parameter, the error remains, but becomes
从对象Ordering中的Tuple9方法开始,对Ordering [A]类型进行隐式展开.
Diverging implicit expansion for type Ordering[A] starting with method Tuple9 in object Ordering.
再次,添加类型参数,使其变为val f2: Int = f[Int]()
帮助.
Again, adding type parameter so that it becomes val f2: Int = f[Int]()
helps.
这是怎么回事?为何编译器可以推断参数A
必须是Int
,而不是参数Ordering[A]
必须是Ordering[Int]
?
What's going on? Why can the compiler infer that parameter A
must be an Int
, but not that parameter Ordering[A]
must be an Ordering[Int]
?
推荐答案
订购实例的生成方式一定存在问题,因为下面的代码有效.我会报告一个错误.
There must be something wrong with the way ordering instances are generated, as the code below works. I'd report a bug.
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()
}
这篇关于从返回类型推断通用隐式参数的类型的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!