Assume the following trait:
trait A {
type B
def +(a:A):A
}
I use an abstract type because I don\'t want to drag around the B in the type s
No need for implicit evidence ... you can use an explicit refinement,
trait A {
self =>
type Self = A { type B = self.B }
type B
def +(a : Self) : Self
}
(note the use of a self type annotation to provide an alias for the outer 'this' allowing the defined and defining B's to be distinguished in the definition of type Self).
REPL transcript,
scala> trait A { self => type Self = A { type B = self.B } ; type B ; def +(a : Self) : Self }
defined trait A
scala> val ai = new A { type B = Int ; def +(a : Self) : Self = this }
ai: java.lang.Object with A{type B = Int} = $anon$1@67f797
scala> val ad = new A { type B = Double ; def +(a : Self) : Self = this }
ad: java.lang.Object with A{type B = Double} = $anon$1@7cb66a
scala> ai + ai
res0: ai.Self = $anon$1@67f797
scala> ad + ad
res1: ad.Self = $anon$1@7cb66a
scala> ai + ad
:9: error: type mismatch;
found : ab.type (with underlying type java.lang.Object with A{type B = Double})
required: ai.Self
ai + ab