简体   繁体   中英

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

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

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM