# Decompose Tuple or Union type into constituents?

Is it possible to iterate over the parameters of a `Tuple` or `Union`? Given `Tuple{A, B, C, D, E, ...}`, is it possible to extract the parameters (`A`, `B`, `C`, `D`, `E`, …)?

A partial solution/hack is something like this, for extracting only a single parameter by position:

``````# Extracts second Tuple parameter in a Tuple type with two elements.
f(::Type{Tuple{S, T}}) where {S <: Any, T <: Any} = T

# Extracts second Tuple parameter.
g(::Type{<:Tuple{<:Any, T}}) where {T <: Any} = T
``````

A related question is: how do I convert an arbitrary tuple type to to a corresponding union, for example `Tuple{A, B, C, D}` would be converted to `Union{A, B, C, D}`. Or Perhaps even something like `Tuple{A, B, Tuple{C, D}}` to the same Union.

I don’t have a real use for this, just being curious.

``````julia> a = (1, 1.2, "a")
(1, 1.2, "a")

julia> typeof(a).types
svec(Int64, Float64, String)
``````
2 Likes

Interesting, never encountered a SimpleVector before!

They are not something users generally need to use. They are used by the compiler because it’s very useful to have a very simple list type that doesn’t have strict types.

3 Likes

reiterating what @Oscar_Smith said …
There really is no good reason for julia developers to ever do anything with `svecs` other than convert them to a tuple or, if appropriate, a vector. The `svec` is not a completed data structure – it does what Base requires of it, and does not do whatever else it might. Their use is a fast track to unexpected occurrences.

Another approach to the proposed function:

``````function eltypesof(x::T) where {T<:Union{Tuple, NamedTuple}}
Tuple( typeof(x).types )
end

function eltypesof(x::Type{T}) where {T<:Union{Tuple, NamedTuple}}
Tuple(x.types)
end

function eltypesof(x::Type{T}) where {T<:NamedTuple}
Tuple(x.types)
end

function eltypesof(x::U) where {U<:Union}
Tuple( Base.uniontypes(x) )
end

eltypesof(::Type{Union{}}) = ()
# or, depending on the intended semantics
# eltypesof(::Type{Union{}}) = Core.TypeOfBottom
``````

It also handles NamedTuples.

1 Like

Why mess about with internal fields and `svec`s instead of just doing

``````julia> typeof.(a)
(Int64, Float64, String)
``````

?

2 Likes

The question as posed is for when only a Tuple type is available as input, not a tuple instance.

1 Like

now do Union

1 Like

Okay, but the accepted answer was on a tuple instance, which is a bit confusing, then.

Or in other words, then assume my answer was a response to this particular line of code, instead of the OP:

Why do this on a tuple?

1 Like

thank you – see the revision above

you can use that as `Tuple(unique(typeof.(a)))`as long as there is no need to go into sub tuples, which is simply unclear in the question.

I have tested the revised routines for empty and nonempty Tuples and NamedTuples and Unions. Let me know if you find a state I have overlooked.

1 Like