Strange behavior of union of types

Sorry, maybe I’m not phrasing this right.

What I mean is, for a parent type X=Union{Vector{T}, Tuple{T, T}} where T <: Number, that Union{Vector{Number}, Tuple{Int,Int}} would not be a subtype—that if the Union contains both Vector and Tuple, that their type parameters must be identical as in the child type Union{Vector{Int}, Tuple{Int,Int}}. If Tuple is not present in this union, however, then the match is looser: Vector{Number} should be a subtype of X. (as a parent type a larger union is easier to match, but as a child type a larger union is harder to match)

In this way, X would be a superset of Vector{<:Number}, a superset of Tuple{T,T} where T<:Number, and a superset of Union{Vector{T}, Tuple{T,T}} where T<:Real, and X would be a subset of Union{Vector, Tuple{T,T}} where T<:Number and a subset of Union{Vector,Tuple}.

Hopefully that makes sense.

EDIT: Changed X to X1 and X2 to clarify

Thanks for the explanation. I think I get what you are describing, but I think there is still a contradiction:

X1 = Union{Vector{T}, Tuple{T, T}} where T <: Number
X2 = Union{Vector{T}} where T <: Number

If I understood correctly, then

  • Vector{Number} should not be in X1
  • Vector{Number} should be in X2

That means your desired behavior

is not possible, since Vector{Number} <: Vector{<:Number} is true in all other contexts. To change that, we would need to change the meaning of Vector{<:Number} itself to allow only concrete types (like the tuple), but I don’t think this is what you implied?

And I think it would be really weird that we add an expression to a union, and it suddenly contains less types.

Hope I’m not missing the point and keep sounding like a broken record :sweat_smile:

It seems my explanation still leaves something to be desired😅

When I said if Tuple is not present in the union, then the match should be looser—I was referring to the union on the LHS, not the RHS.

Thus, Vector{Number} <: X, because the LHS is not unioned with a Tuple.

I’ve made an edit to my previous post to clarify what I am referring to with X and what I thought you are referring to.

Ok, then I misunderstood. You mean the LHS here?

Vector{Number} <: X
Tuple{Int,Int} <: X
Union{Vector{Number}, Tuple{Int,Int}} <: X

But now I’m lost… If Vector{Number} should be a subtype (read: subset) of X and also Tuple{Int, Int} should be a subtype of X, then their union should be as well, in my opinion. Otherwise I just wouldn’t call it “union” and make the whole thing work analogously to sets (but this is what the developers had in mind, according to Jeff’s talk linked above).