It works if you override the type members like this. Scala does not infer them automatically.
class A extends Entity {
type E = A
type S = Something[A]
def in = InA
object InA extends Something[A]
}
class B extends Entity {
type E = B
type S = Something[B]
def in = InB
object InB extends Something[B]
}
class C extends Entity {
type E = C
type S = Something[C]
def in = InC
object InC extends Something[C]
}
Another option would be to do away with type members and only use type parameters.
trait Entity[E <: Entity[E]] {
def in: Something[E]
}
trait Something[E <: Entity[E]] {
def doSomething {
// something
}
}
class A extends Entity[A] {
def in = InA
object InA extends Something[A]
}
class B extends Entity[B] {
def in = InB
object InB extends Something[B]
}
class C extends Entity[C] {
def in = InC
object InC extends Something[C]
}
val entities = Seq[Entity[_]]()
entities.map(_.in.doSomething)
This uses a technique called F-bounded polymorphism.