In a nutshell, let’s say I have a trait A<T> { ... }; then another trait B { type X; ... }. How can I state that type X in B always implements A for all T?
Something like trait B { type X : A<*>; ... } but this is not valid code.
I believe we miss an existential quantifier in associated type definitions (and possibly other places).
Advice from IRC suggested definining B with a parameter, ie. trait B<T> {type X : A<T>; ... } however this does not work as soon as some other items in B wish to exploit the genericity of X; for example:
trait A<T> { type O; ... }
trait B<T> {
type X : A<T>;
fn transform<U>(x : U) -> <X as A<U>>::O;
// ^^^^
// Error: X does not implement A<U>, only A<T>
}
Were it possible to write the generic form this error would evaporate:
indent preformatted text by 4 spaces
trait A<T> { type O; ... }
trait B {
type X : A<*>;
fn transform<U>(x : U) -> <X as A<U>>::O;
// ^^^^ OK
}
I first submitted this as this issue on the bug tracker, which in turn illustrates an attempt to shoe-horn a reduced yet powerful form of HKTs in the current associated type machinery, inspired from this example from last year.
However do not let this mention of HKTs distract from the present discussion: even if HKTs are to be implemented using a different approach, I believe that existential implementation specifiers such as proposed above would still be useful. Meanwhile, if you are really interested in HKTs, notice that they would come for free as a by-product of the existential quantification described above.