Both Tuple
and Union
are special in Julia and can’t just be thought of as regular parametric types. The weirdness of Tuple
is described quite well here, but the section for Union
types could probably be improved.
The first thing to note about Union
is that there can never be an instance of an object that has a union type as its type. Instances must always have a concrete type, unions just represent a set of types that an object could be, and can also allow the compiler to optimize small unions, for example. As such it simply isn’t possible to dispatch just based on whether something is a union type, since the actual object passed to the function will always have a concrete type, and the function being dispatched on doesn’t know whether your code is type stable or not.
As such, what you are trying to do doesn’t make much sense, since Union
is not an abstract type, that Union{Int,Float64}
is a subtype of, but instead, Union{Int,Float64}
is only a subtype of types, that both Int
and Float64
are a subtype of, so e.g. Union{Int,Float64} <: Real == true
. If you want to check, whether a type (not an object) is a union type, you could to this with Union{Int,Float64} isa Union
, for example, since Union
is not the supertype of union types, but union types are actually instances of type Union
.
@hendri54 Union types actually don’t rely on promote
at all, but instead, when checking whether they are a subtype of something, it is checked, whether every member of the union is a subtype, so it’s easiest to just think of union types as set unions, and <:
as checking whether the argument on the left is a subset of the one on the right. Also note that Union{Any}
is just equivalent to Any
and Union{UInt8,Real}
is equivalent to Real
, since UInt8
is just a subtype of Real
. Order also doesn’t matter for union types.
I hope this hasn’t been too confusing, and it cleared at least some things up. Anybody feel free to correct me, if I glossed over some things.