У меня есть довольно простой пример, когда одна функция foo()
, которая принимает неявный аргумент типа A
, пытается вызвать другую функцию bar()
, которая принимает неявный аргумент типа B
. В проекте, где я столкнулся с этим вопросом, B
содержит подмножество функциональных возможностей A
, поэтому я хотел бы обеспечить неявное преобразование из A
в B
для создания кейсов как в этом примере бесшовные.
Реализация этого с использованием неявного преобразования B.implicitConversion()
работает как ожидалось. Следующий код принят scalac
2.13.0:
trait A
trait B
object B {
// implicit class ImplicitClass(value: A) extends B
implicit def implicitConversion(implicit se: A) = ???
}
class Test {
def foo()(implicit a: A) = bar()
def bar()(implicit b: B) = ???
}
Как ни странно, реализация преобразования с использованием неявного класса ImplicitClass
не работает (удаляя определение implicitConversion()
и добавляя определение ImplicitClass
). Код отклонен scalac
:
$ scalac 'Test.scala:12: error: could not find implicit value for parameter b: B
def foo()(implicit a: A) = bar()
^
one error found
Я бы предположил, что в такой ситуации неявные классы и неявное преобразование являются взаимозаменяемыми. Чего мне здесь не хватает, почему два способа предоставления конверсии не эквивалентны?