i'm trying to understand the behavior of the compiler in this situation
object ImplicitTest extends App {
def foo[T](implicit x: (String => T)): T = ???
implicit val bar = (x: String) => x.toInt
foo
}
the code above does not compile and gives the following error:
ambiguous implicit values: both method $conforms in object Predef of type [A]⇒ <:<[A,A] and value bar in object ImplicitTest of type ⇒ String ⇒ Int match expected type String ⇒ T
as the error says my implicit value is conflicting with another implicit defined in Predef... based on this it seems there is no way to declare an implicit parameter to a function converting a value from a known type to an unknown (generic) type.
Is this due to some technical limitation on the compiler or is just the way it is supposed to work, and i'm violating some constraints i'm not aware of?
You're not providing a type parameter to
foo
when you call it (and there is no other way to infer it, for the following reason), so the compiler is having trouble finding the right one, and the right implicit.You have the implicit
bar: String => Int
in scope, but you also have implicits inPredef
that create instances of=:=
and<:<
which both extendA => B
, and create implicitString => A
s. The compiler is looking for some implicit functionString => T
forfoo
, but it's not sure which one, and you have multiple in scope.bar
will not take precedence because you haven't specified the specificString => T
it's looking for.This will work: