Why Unions dont inheret its union?

Why does this return false

IntOrString = Union{Int,AbstractString}
(IntOrString <: String, IntOrString <: Int)

I am not questioning the decision, just curious to know the reason behind it
Also while we are at it why are unions not a DataType

Union <: DataType
DataType <: Union

Because, in your example, an Int is not a subtype of String. Think about it like sets. You have the set of all Int unioned with all AbstractString. This is clearly bigger than the set of String. In fact you have:

julia> String <: IntOrString

I think I might have figured it out
Union are not treated as a DataType, because typeof(), can never return a Union

The type of a value can never be a Union

But now this make me think that

IntOrString <: String

should instead raise an error, not just return false

No. It is critical for Julia that <: return either true or false for every combination of types.


I’m not sure what you mean but note:

julia> abstract type Foo end

julia> Foo isa DataType

but typeof can never return Foo.


It can never return Foo, because Foo is an abstract type, that cannot be instantiated
Only concrete type can be instantiated

Exactly, IntOrString is not a type or a DataType , its more like a function on Types, but is not itself a type , hence the raise an error make sense to me

Yes, I know, my point was that you said

and I gave an example of where something is treated as a DataType even though typeof cannot return it.

1 Like

Unions not being of type DataType has nothing to do with the fact that IntOrString <: String == false.

Let’s say you have a cage whose dweller has the type const HamsterOrBird = Union{Hamster, AbstractBird}. When you ask HamsterOrBird <: Canary, it means “if I know that there is a HamsterOrBird in the cage, can I be sure that the caged creature is a Canary?”

Maybe you meant the subtyping in the opposite direction? IntOrString >: String is true, meaning that if x isa String then x isa IntOrString.


Also note that

julia> Union{Int,UInt} <: Integer

julia> Union{Int,UInt}
Union{Int64, UInt64}

julia> typeof(Union{Int,UInt})

julia> typeof(Integer)

The typeof of a Type has little to do with the subtype relation.