Let T1, T2, T3
be three types. We also define two given instances of the Conversion
class so that the compiler can go from T1
to T2
and from T2
to T3
.
The following code then compiles fine:
type T1
type T2
type T3
given Conversion[T1, T2] with
override def apply(x: T1): T2 = ???
given Conversion[T2, T3] with
override def apply(x: T2): T3 = ???
val t1: T1 = ???
val t2: T2 = t1
val t3: T3 = t2
But what happens when we try to go from T1
to T3
? The compiler won't let us:
val t3: T3 = t1
^^
Found: (t1: T1)
Required: T3
My Question: is there a specific reason why the compiler cannot natively (see workaround) chain conversions ?
My Workaround: it turns out that we can implicitly tell to compiler how to chain conversions by defining a generic conversion from A
to C
, given that we know how to convert A
to B
and B
to C
:
given [A, B, C](using conv1: Conversion[A, B])(using conv2: Conversion[B, C]): Conversion[A, C] with
override def apply(x: A): C = conv2.apply(conv1.apply(x))
To compiler can now chain conversions:
val t3: T3 = t1 //OK
Bonus point: this new generic conversion can even recursively call itself, meaning that we can chain infinite conversions.