# Problem with the Tuple type

Hi! I’m new to this forum, though not to Julia. I have a question.
Recently I tried to build a function meant to accept as input only vectors of n-tuples (without specifying n).

For example, consider the following:

``````X = [(i,j) for i in 1.:2 for j in 1:3.]
``````

whose type is Array{Tuple{Float64,Float64},1}, an array of 2-tuples.

My intention is to have a function like the following:

``````function test_function(X::Array{Tuple, 1})
println("good!")
end
``````

in hopes of allowing the function to take arrays containing Tuples of any kind. In my head this makes sense as Tuple is the parent type of Tuple{Float64,Float64}. I tried to test if this would work using the following two lines.
First, I tested if the elements of X where Tuples, which the should’ve by definition.

``````julia> isa(X, Tuple)
true
``````

sure enough, it works. Then I tested if X itself was an array of tuples

``````julia> isa(X, Array{Tuple, 1})
false
``````

It turns out it… isn’t? I then tested using the explicit type of the Tuples:

``````julia> isa(X, Array{NTuple{2, Float64}, 1})
true
``````

It behaves as though Tuple were not the parent type of Tuple{Float64,Float64}. Though testing I found it should be:

``````julia> Tuple{Float64,Float64} <: Tuple
true
``````

However… Julia does not list any subtypes of the Tuple

``````julia> subtypes(Tuple)
Type[]
``````

My overall problem is I still can’t build a function that takes only an array of tuples; what I imagine should’ve been the type Array{Tuple,1}, or even Vector{Tuple}, but now I believe something weird is going on with the Tuple type itself.

Maybe this helps you

``````function test_function(X::Array{T, 1}) where T <: Tuple
println("good!")
end

@show test_function(Vector{Tuple{Float64}}())
@show test_function(Vector{Tuple{Float64, Float64}}())
``````
``````Vector{<:Tuple}
``````

?

Tuples are weird, but I think this is another case of: Vector{Int} <: Vector{Real} is false??? · JuliaNotes.jl

1 Like

Vectors (and Arrays) are really `Vector{T}` and `Array{T,N}`

• where N is the number of dimensions for the array.
``````julia> Vector{T} where T
Vector (alias for Array{T, 1} where T)
``````

For a function to accept an argument `v`, `v::Vector{T}` where `T` is any Tuple
and to ignore other argument types:
(edited to use the specific approach that @stevenjg shares next)

``````julia> istuplevec(v) = false

# istuplevec(v::Vector{T}) where {T allows any kind of Tuple}
# istuplevec(v::Vector{T}) where { isa(T, ::Type{Tuple}) }
# istuplevec(v::Vector{T}) where {T<:Tuple} = true

julia> istuplevec(v::AbstractVector{<:Tuple} = true

julia> istuplevec([(1,2), (3,4)])
true
julia> istuplevec([(1,2), (3,4,5)])
true
julia> istuplevec([(1,2), ("three",4.0,5//1)])
true
julia> istuplevec([(1,2), (3,4), 5])
false
``````

if you want to allow only Vectors of equilength Tuples
where all the elements are of a shared type

``````julia> isuniformtuplevec(v) = false
julia> isuniformtuplevec(v::AbstractVector{<:NTuple{N}) where {N} = true

julia> isuniformtuplevec([(1,2),(3,4)])
true
julia> isuniformtuplevec([(1,2),(3,4,5)])
false
julia> isuniformtuplevec([(1,2),('3',"4")])
false
``````

Even better, use `test_function(X::AbstractVector{<:Tuple})`, which allows any type of 1d array (e.g. views of arrays), not just `Array`, of any type of tuple.

5 Likes