Hi,
I tried to write methods for a function (taking types as arguments) that should dispatch only if one argument supertypes the other, e.g.,
a_supertypes_b( a::Type, b::Type ) = "no"
a_supertypes_b( ::Type{SUP}, ::Type{SUB} ) where {SUP, SUB<:SUP} = "yes"
Of course, my use case was not checking the type relation, but the method signatures looked similar.
Now, I also wanted a custom method for the case that the supertype SUP
was a Union type.
Is there a generic way to dispatch on “types of Union types”?
First thought:
a_supertypes_b( ::Type{SUP}, ::Type{SUB} ) where {SUP<:Union, SUB<:SUP} = "yes_for_union"
This does not get called:
T32 = Union{Int32, Float32}
a_supertypes_b( T32, Int32 ) == "yes" # not "yes_for_union"
I think, this is because T32 isa Type{<:Union}
is false
.
In fact, for any Union type, typeof
returns simply Union
.
This is also why
a_supertypes_b( :: SUP, :: Type{SUB} ) where {SUP<:Union, SUB<:SUP} = "yes_for_union"
won’t get called for (T32, Int32)
: Then SUP == Union
and it does not hold that Int32 <: Union
.
In all of the above examples, the method for union types does not get called, because typeof(T32) != Type{T32}
which would discourage from using the dispatch mechanism for types of union types.
However, I know that I can use handwritten method signatures, e.g.,
T64 = Union{Int64, Float64}
f( :: Type{Union{Int32, Float32}} ) = 32
f( :: Type{T64} ) = 64
# now this is true:
f(T32) == 32 && f(T64) == 64
and
a_supertypes_b( :: Type{SUP}, SUB ) where {SUP<:T32, SUB<:SUP} = "yes_T32"
would get called: a_supertypes_b( T32, Int32 ) == "yes_T32"
.
So in the above example, for the union type T32
, Julia dispatches on Type{T32}
(and not on typeof(T32) == Union
).
Can I do this generically, if the exact union types are not known beforehand?
I guess, one difficulty prohibiting a generalization of the last method definition for arbitrary union types lies in the fact, that there is no defining supertype of union types. That is, there is no SUP_UNION
such that T <: SUP_UNION
for any union type T
, which would allow for
a_supertypes_b( :: Type{SUP}, SUB ) where {SUP<:SUP_UNION, SUB<:SUP} = "yes_for_union"
Or does such a supertype exist?
Am I overlooking something?
Thanks in advance!