Why `Tuple{Vararg{T, 2} where T} == Tuple{Any, Any}`?

Why this is the case, instead of being a UnionAll like Arrays?

Tuples are covariant as opposed to all other parametric types that are invariant.
The reason for this is that tuples are used in signature matching in method dispatch, see https://docs.julialang.org/en/latest/manual/types/#Tuple-Types-1.

Here is an example of this distinction:

julia> Tuple{Int} <: Tuple{Any}

julia> Vector{Int} <: Vector{Any}

julia> Vector{Int} <: Vector{<:Any}

You might also check out an answer on StackOverflow that I have just written on a related topic.


I was thinking in the same direction too. I managed to convince myself after testing:

Union{Tuple{Int}, {Tuple{Any}} == Tuple{Any}