I'm having a problem with a recursive self-type that should correspond to a type member:
trait Elem { me =>
type Peer
import me.{Peer => Peer0}
type This <: Elem { type Peer = Peer0 }
def mkCopy(): This
}
Now I want to define a convenient trait:
trait ImmutableImpl extends Elem {
_ : This =>
def mkCopy(): This = this
}
This doesn't work, because "error: not found: type This" :(
Next attempt:
trait ImmutableImpl[Repr] extends Elem {
_ : Repr =>
type This = Repr
def mkCopy(): This = this
}
This fails with "Error: overriding type This ... This has incompatible type".
I can do only this abomination:
trait ImmutableImpl[Peer0, Repr <: Elem { type Peer = Peer0 }] extends Elem {
_ : Repr =>
type Peer = Peer0
type This = Repr
override def mkCopy(): This = this
}
class IntElem extends ImmutableImpl[Int, IntElem]
In the real case I have more type members, so that makes this last approach useless, as it's much more boiler plate that implementing the mkCopy
by hand each time.
Any ideas?
My workaround is to relax the refinement on This
, as it appears to not be required in my API in the end:
trait Elem { me =>
type Peer
// import me.{Peer => Peer0}
type This <: Elem // { type Peer = Peer0 }
def mkCopy(): This
}
trait ImmutableImpl[Repr <: Elem] extends Elem {
_ : Repr =>
override type This = Repr
def mkCopy(): This = this
}
class IntElem extends ImmutableImpl[IntElem] {
type Peer = Int
}