Here is one idiomatic scala 2 example:
trait Box {
type Content
val content :Content
}
implicit class BoxExtension[B <: Box](private val self :B) extends AnyVal {
def map[O](f :self.Content => O)(implicit mapper :Mapper[B, O]) :mapper.Res =
mapper(self)(f)
}
trait Mapper[B <: Box, O] {
type Res
def apply(box :B)(f :box.Content => O) :Res
}
As you see, it has already been partly converted to the usage of path dependent types. But how to create an implicit value of Mapper
for an O
type which references self.Content
(such as O =:= self.Content
itself)?. Ideally a solution which would have straightforward equivalence between Scala 2 and Scala 3.
You can make an implicit def for this. Since Dotty doesn't allow type projections on abstract types, you'll need an extra type parameter. Also, I had to make
self
public because it was used in the signature ofmap
.Full example
I would normally suggest using type parameters for
Box
and (and an extra one forMapper
) instead, but it gets a little complicated. Perhaps you could turnBoxExtension
into something like this, withC
as an extra parameter:If you're open to using just Dotty and not cross-compiling, you can do this