I’m writing some code where I expect a vector of 2-element tuples but I can’t figure out how to type the parameters in such a way that it’s clear what needs to be passed but not so restrictive that type promotion is thrown out of the window.

I thought the following would work (I simplified the code to the minimum):

``
f(v::Vector{Tuple{Real, Real}}) = v

f([(1, 1)])

But this results in the following error:

ERROR: MethodError: no method matching f(::Array{Tuple{Int64,Int64},1})
Closest candidates are:
f(::Array{Tuple{Real,Real},1}) at none:1
Stacktrace:
[1] top-level scope at none:1

So I thought I'd simplify things as follows:

f(v::Vector{Tuple}) = v

But I get the same type of error:

ERROR: MethodError: no method matching f(::Array{Tuple{Int64,Int64},1})
Closest candidates are:
f(::Array{Tuple,1}) at none:1
f(::Array{Tuple{Real,Real},1}) at none:1
Stacktrace:
[1] top-level scope at none:1

Is there any way that I can type this in such a way that I can actually call the function with any type of Real elements in the tuples?
Thanks in advance,
Stef

function f(v::Array{Tuple{T1,T2},1}) where {T1,T2 <: Real}

I had the same problem yesterday. It turns out that using Real as is does not work because of a concept called ‘invariance’ (see the documentation on Types).

So, what you have to do is indicate the compiler that it can be any type that belongs to Real. That is what the where {T1,T2 <: Real} part means.

I’d go for f(v::Vector{T}) where T<:Tuple{Real,Real}. That works because tuples are covariant on parameters (i.e. T<:Pair{Real,Real} wouldn’t work the same, and one would need T<:Pair{<:Real, <:Real}).

If both tuple elements are expected to have the same type, f(v::Vector{T}) where {T<:Tuple{R,R}, R<:Real} may be used.

Vector{Tuple} is a concrete type that can hold any tuple, so, from Julia type system point of view, it is different from Vector{Tuple{Int,Int}} which can only hold tuples of two Ints.

Also, I’d recommend using AbstractVector in the signature in case you’d like to pass a vector view at some point in the future.