Suppose you want to define a class like this:
class Some<A, B, M> where M == Either<A, Self.U> {
enum U { case a(A), b(B) }
}
enum Either<A, B>{ case a(A), b(B) }
Why does compiler throws an error about that it is not possible to reference the nested type?
1 Like
Lantua
2
That cyclical referencing looks very scary, I think you can better express that requirement as:
class Some<A, B> {
enum U { case a(A), b(B) }
typealias M = Either<A, U>
}
You need to fully specify the generic placeholders to identify nested types. So you need M (and A, B) to define U, then you need U to constrain M. I'm not even sure how that's suppose to work.
1 Like
I tried that, but it shows the same issue.
My initial intuition was that it is a process with two steps, first of which is an inference of A and B and second is a reference to Self.U, that is gonna be parametrized.
Would like to know whose flaw it is: mine or the language's.
Lantua
4
Thing is, it is Some<A, B, M>.U, not U<A, B>. You need to know M before considering U even if M doesn't appear inside U. Like in this example:
struct Foo<Value> {
enum A { }
}
Foo<Int>.A.self == Foo<Int>.A.self // true
Foo<Int>.A.self == Foo<String>.A.self // false
Foo.Value is considered part of A. I don't think it's a flaw, just that your expectation of U doesn't match that of the language's.
Alright, thank you for feedback.
ps. It is interesting that even though the nested type signature does not dependent on a parent type signature, it is still treated as contravariant. Is that a correct behaviour?
Lantua
6
They're actually invariant. And I believe that that'd be the expected behaviour if we're to treat the unused generic as significant.