Inferring type of generic implicit parameter from return type

廉价感情. 提交于 2019-11-28 00:41:13

问题


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

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.

However, throwing an Ordering[A] into the mix:

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

results in this compile error:

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

If I add the type information when invoking f(), it compiles:

val f2: Int = f[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).

Note that if we remove implicit a: A and leave only the Ordering implicit parameter, the error remains, but becomes

Diverging implicit expansion for type Ordering[A] starting with method Tuple9 in object Ordering.

Again, adding type parameter so that it becomes val f2: Int = f[Int]() helps.

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]?


回答1:


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


来源:https://stackoverflow.com/questions/36388954/inferring-type-of-generic-implicit-parameter-from-return-type

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!