julia> 1 isa Int
true
julia> (1,) isa Tuple{Int}
true
julia> Int isa Type{Int}
true
julia> (Int,) isa Tuple{Type{Int}} # ???
false
And how does dispatch work if this supertyping doesn’t work for method signatures as tuple types?
julia> 1 isa Int
true
julia> (1,) isa Tuple{Int}
true
julia> Int isa Type{Int}
true
julia> (Int,) isa Tuple{Type{Int}} # ???
false
And how does dispatch work if this supertyping doesn’t work for method signatures as tuple types?
typeof((Int,)) is not Tuple{Type{Int}}, but Tuple{DataType}, and accordingly this does work:
julia> (Int,) isa Tuple{DataType}
true
The point as I understand it is related to:
julia> isconcretetype(DataType)
true
julia> isconcretetype(Type{Int})
false
Counterintuitive? I’d say yes, but correctly documented:
For each type
T,Type{T}is an abstract parametric type whose only instance is the objectT.
(emphasis added).
This means that once you wrap a DataType (Int, Float64…) inside a Tuple, it is no longer possible to distinguish it from any other DataType by looking into the type of that tuple, just as you cannot distinguish (1,) from (2,) only by the tuple’s type - you have to access directly the members of the tuple to do it.