Tipo inferido de parámetro implícito genérico del tipo de retorno
Digamos que tengo una clase simple como esta
abstract class Foo {
implicit val impInt: Int = 42
def f[A]()(implicit a: A): A
val f2: Int = f()
}
Al declarar valf2
, el compilador puede inferir que el tipo de parámetro implícito de funciónf
esInt
porque ese tipo es el mismo que el tipo de resultado, y el tipo de resultado debe coincidir con el tipo de valorf2
, cual esInt
.
Sin embargo, arrojando unOrdering[A]
en la mezcla:
def f[A]()(implicit a: A, m: Ordering[A]): A
val f2: Int = f()
da como resultado este error de compilación:
Valores implícitos ambiguos: tanto el valor StringCanBuildFrom en el objeto Predef de tipo => scala.collection.generic.CanBuildFrom [String, Char, String] y el método $ se ajustan en el objeto Predef de tipo [A] => <: <[A, A] coincide con el tipo A esperado
Si agrego la información de tipo al invocarf()
, compila:
val f2: Int = f[Int]()
Primero encontré el caso con el orden implícito y pensé que tiene que ver con que Scala infiere de izquierda a derecha; Pensé que no puede coincidir con el tipo de retorno primero yentonces inferir el tipo de parámetro (implícito) def
. Pero luego probé el caso sin un pedido implícito y vi que funciona: infirió quef
debe ser parametrizado porInt
porque el tipo de retorno tiene que ser unInt
(porquef2
es unInt
)
Tenga en cuenta que si eliminamosimplicit a: A
y deja solo el parámetro implícito Ordenar, el error permanece, pero se convierte
Expansión implícita divergente para el tipo Ordering [A] comenzando con el método Tuple9 en Object Ordering.
Nuevamente, agregando parámetro de tipo para que se conviertaval f2: Int = f[Int]()
ayuda
¿Que esta pasando? ¿Por qué el compilador puede inferir ese parámetro?A
debe ser unInt
, pero no ese parámetroOrdering[A]
debe ser unOrdering[Int]
?