Я думал, что понимаю, что scala implicits до недавнего времени сталкивался с какой-то странной проблемой.
В моем приложении у меня есть несколько классов домена
case class Foo(baz: String)
case class Bar(baz: String)
И класс, способный построить объект домена из строки. Это может быть подклассифицировано для реальной десериализации, это не имеет значения.
class Reads[A] {
def read(s: String): A = throw new Exception("not implemented")
}
Далее, существуют неявные десериализаторы
implicit val fooReads = new Reads[Foo]
implicit val barReads = new Reads[Bar]
И помощник для преобразования строк в один из классов домена
def convert[A](s: String)(implicit reads: Reads[A]): A = reads.read(s)
К сожалению, при попытке использовать его
def f(s: String): Foo = convert(s)
Я получаю ошибки компилятора, такие как
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)
^
Мне код кажется простым и правильным. Reads[Foo]
и Reads[Bar]
- это совершенно разные типы, что в этом двусмысленно?
Реальный код намного сложнее и использует play.api.libs.json
, но этой упрощенной версии достаточно, чтобы воспроизвести ошибку.