Скажем, у меня есть два набора классов, и первый набор наследует от Foo, а второй набор наследует от Bar.
class Foo
class Baz extends Foo
class Bar
class Qux extends Bar
Я хочу создать общую неявную функцию преобразования, которая преобразует любой Foo в Bar, если в области есть неявный тип конвертера.
trait Converter[A <: Foo, B <: Bar] {
def convert(a : A) : B
}
implicit object BazToQuxConverter extends Converter[Baz, Qux] {
def convert(a : Baz) : Qux = new Qux
}
implicit def FooToBar[A <: Foo, B <: Bar](a : A)(implicit converter : Converter[A, B]) : B = converter.convert(a)
К сожалению, это не работает, как я ожидал. Когда я подключу следующие строки к REPL:
val a : Baz = new Baz
val b : Qux = a
... Я получаю следующую ошибку:
<console>:17: error: type mismatch;
found : Baz
required: Qux
val b : Qux = a
^
Есть ли способ заставить это работать? Ближайшим, к которому я пришел, является следующее:
implicit def BadFooToBar[A <: Foo, B <: Bar](a : A)(implicit converter : Converter[A, _]) : B = converter.convert(a).asInstanceOf[B]
Это работает для моего предыдущего примера, но это не очень безопасно.
class Qax extends Bar
val a : Baz = new Baz
val b : Qax = a
Это будет скомпилировано просто отлично, но оно будет взорваться во время выполнения, потому что Qux
(результат converter.convert(a)
) нельзя отнести к Qax
(asInstanceOf[Qax]
). В идеале я хочу, чтобы эта строка была поймана во время компиляции, так как в области не существует Converter[Bax,Qax]
.