Say I have two sets of classes and the first set inherits from Foo and the second set inherits from Bar.
class Foo
class Baz extends Foo
class Bar
class Qux extends Bar
I want to make a generic implicit conversion function that converts any Foo to Bar given there is an implicit converter type in scope.
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)
Unfortunately, this doesn't seem to work as I would expect it to. When I plug in the following lines to the REPL:
val a : Baz = new Baz
val b : Qux = a
...I get the following error:
<console>:17: error: type mismatch;
found : Baz
required: Qux
val b : Qux = a
^
Is there any way to get this to work? The closest I've been able to come is the following:
implicit def BadFooToBar[A <: Foo, B <: Bar](a : A)(implicit converter : Converter[A, _]) : B = converter.convert(a).asInstanceOf[B]
This does work for my previous example, but it's not very type-safe.
class Qax extends Bar
val a : Baz = new Baz
val b : Qax = a
This will compile just fine, but it will blow up at run-time because a Qux
(the result of converter.convert(a)
) can't be cast to Qax
(asInstanceOf[Qax]
). Ideally, I want it so that the above line will be caught at compile time since there isn't any Converter[Bax,Qax]
in scope.