Sharpen Tuple Element Types

struct Foo end

typeof((Foo, ))

yields

Tuple{DataType}

rather than something more precise like

Tuple{Type{Foo}}

This is causing me some type-instability problems.

Question: is there a way to produce a Tuple whose type includes Type{Foo} rather than Type{DataType}?

n.b. I’ve tried convert(Tuple{Type{Foo}}, (Foo, )) but can’t seem to get it to work.

You can make such a tuple type with:

julia> weirdtypeof(t::Tuple) = Tuple{(tel isa Type ? Type{tel} : typeof(tel) for tel in t)...}
weirdtypeof (generic function with 1 method)

julia> weirdtypeof((Foo, 1, Int, 7.8im))
Tuple{Type{Foo}, Int64, Type{Int64}, ComplexF64}

but it won’t be the type of the tuple:

julia> (Foo, ) isa Tuple{Type{Foo}}
false

julia> (Foo, ) isa Tuple{DataType}
true

Types are instances of DataType, Union, UnionAll, etc, not singleton instances, so Tuple{DataType} is the only right answer there. That’s usually good because it is wasteful to compile for each type when they share structure, but Type{T} exists for dispatch because sometimes it is beneficial to get around.

1 Like