Inferindo o tipo de parâmetro implícito genérico do tipo de retorno

Digamos que eu tenha uma classe simples como esta

abstract class Foo {
  implicit val impInt: Int = 42
  def f[A]()(implicit a: A): A
  val f2: Int = f()
}

Ao declarar valf2, o compilador pode inferir que o tipo de parâmetro implícito da funçãof éInt porque esse tipo é igual ao tipo de resultado e o tipo de resultado precisa corresponder ao tipo de valorf2, qual éInt.

No entanto, jogando umOrdering[A] na mistura:

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

resulta neste erro de compilação:

Valores implícitos ambíguos: o valor StringCanBuildFrom no objeto Predef do tipo => scala.collection.generic.CanBuildFrom [String, Char, String] e o método $ está em conformidade no objeto Predef do tipo [A] => <: <[A, A] corresponde ao tipo A esperado

Se eu adicionar as informações de tipo ao chamarf(), compila:

val f2: Int = f[Int]()

Primeiro, encontrei o caso com pedidos implícitos e pensei que tivesse a ver com Scala deduzindo da esquerda para a direita; Eu pensei que não é capaz de corresponder ao tipo de retorno primeiro eentão inferir o tipo de parâmetro (implícito) def. Mas então eu tentei o caso sem uma ordem implícita e vi que ele funciona - inferiu quef deve ser parametrizado porInt porque o tipo de retorno deve ser umInt (Porquef2 é umInt)

Observe que se removermosimplicit a: A e deixe apenas o parâmetro implícito Ordering, o erro permanece, mas se torna

Expansão implícita divergente para o tipo Ordering [A] começando com o método Tuple9 no objeto Ordering.

Novamente, adicionando o parâmetro type para que ele se torneval f2: Int = f[Int]() ajuda.

O que está acontecendo? Por que o compilador pode inferir esse parâmetroA deve ser umInt, mas não esse parâmetroOrdering[A] deve ser umOrdering[Int]?

questionAnswers(1)

yourAnswerToTheQuestion