I've been thinking I understand scala implicits until recently faced strange problem.
In my application I have several domain classes
case class Foo(baz: String)
case class Bar(baz: String)
And a class that is able to construct domain object from a string. It could be subclassed to do real deserialization it doesn't matter.
class Reads[A] {
def read(s: String): A = throw new Exception("not implemented")
}
Next, there are implicit deserializers
implicit val fooReads = new Reads[Foo]
implicit val barReads = new Reads[Bar]
And a helper to convert strings to one of domain classes
def convert[A](s: String)(implicit reads: Reads[A]): A = reads.read(s)
Unfortunatelly, when trying to use it
def f(s: String): Foo = convert(s)
I get compiler errors like
error: ambiguous implicit values:
both value fooReads of type => Reads[Foo]
and value barReads of type => Reads[Bar]
match expected type Reads[A]
def f(s: String): Foo = convert(s)
^
To me code seems simple and right. Reads[Foo]
and Reads[Bar]
is a completely different types, what is ambiguous about it?
The real code is much more complicated and uses play.api.libs.json
but this simplified version is sufficient to reproduce the error.