I don't think it's possible in scala to do what you want.
If I were to:
class Base { type A }
class Other extends Base
class Sub extends Other
Now... we want type A to refer to "the type of the subclass."
You can see that from the context of Base
, it's not particularly clear (from the compiler's perspective) what the specific "type of the subclass" means, nevermind what the syntax would be to refer to it in the parent. In Other
it would mean an instance of Other
, but in Sub it might mean an instance of Sub
? Would it be OK to define an implementation of your method returning an Other
in Other
but not in Sub
? If there are two methods returning A
's, and one is implemented in Other
and the other in Sub
, does that mean the type defined in Base has two different meanings/bounds/restrictions at the same time? Then what happens if A
is referred to outside of these classes?
The closest thing we have is this.type
. I'm not sure if it would be theoretically possible to relax the meaning of this.type
(or provide a more relaxed version), but as implemented it means a very specific type, so specific that the only return value satisfying def foo:this.type
is this
itself.
I'd like to be able to do what you suggest, but I'm not sure how it would work. Let's imagine that this.type
meant... something more general. What would it be? We can't just say "any of the defined types of this
," because you wouldn't want class Subclass with MyTrait{type A=MyTrait}
to be valid. We could say "a type satisfying all of the types of this
," but it gets confusing when someone writes val a = new Foo with SomeOtherMixin
... and I'm still not sure it could be defined in a way that would enable an implementation of both Other
and Sub
defined above.
We're sort-of trying to mix static and dynamically defined types.
In Scala, when you say class B { type T <: B }
, T
is specific to the instance, and B
is static (I'm using that word in the sense of static methods in java). You could say class Foo(o:Object){type T = o.type}
, and T
would be different for every instance.... but when you write type T=Foo
, Foo
is the statically specified type of the class. You could just as well have had an object Bar
, and had referred to some Bar.AnotherType
. The AnotherType
, since it's essentially "static," (though not really called "static" in Scala), doesn't participate in inheritance in Foo
.