I don’t understand the following behavior:
julia> typeof((a = (b = 1,),)) <: NamedTuple{(:a,), Tuple{<:NamedTuple}}
false
julia> typeof((a = (b = 1,),)) <: NamedTuple{(:a,), Tuple{NT}} where {NT <: NamedTuple}
true
I don’t understand the following behavior:
julia> typeof((a = (b = 1,),)) <: NamedTuple{(:a,), Tuple{<:NamedTuple}}
false
julia> typeof((a = (b = 1,),)) <: NamedTuple{(:a,), Tuple{NT}} where {NT <: NamedTuple}
true
This is due to two confusing things:
Tuple is covaritant w.r.t its type parameters, whereas NamedTuple is invariant.A{B{C}} where {C <: D} is different from A{(B{C} where {C <: D})}. In the former, B is treated as a TypeVar, so it’s equivalent to A{<:B{C<:D}}.So, let’s look at (a = (b = 1,),).:
NamedTuple{(:a,), Tuple{NamedTuple{(:b,), Tuple{Int}}}}UnionAll type NamedTuple{(:a,), <:Tuple}.
Tuple{NamedTuple{(:b,), Tuple{Int}}}} <: TupleNamedTuple{(:a,), Tuple}, which is what your first line queries, because NamedTuple is invariant.Your second line has NamedTuple{(:a,), Tuple{NT}} where {NT <: NamedTuple}.
where is outside the outer parenthesis, there where applies to the outermost NamedTuple - in other words, it makes the NamedTuple a UnionAllNamedTuple{(:a,), <:Tuple{<:NamedTuple}}. And this is clearly a correct supertypeNamedTuple{(:a,), (Tuple{NT} where {NT <: NamedTuple})} is NOT a supertype of the given name dtuple, because the where is inside the outer parenthesisThanks for the quick reply and the explanation regarding UnionAll types ![]()