How to define function signature with nested types of tuples, functions, vectors, and reals?

What am I doing wrong here?

julia> function fcn(xvec::AbstractVector{T}, ytup::Tuple{V}, ztup::Tuple{V}) where {T <: Real, V <: AbstractVector{T}}
       @show typeof(xVec)
       @show typeof(ytup)
       @show typeof(ztup)
       end
fcn (generic function with 1 method)

julia> fcn([1, 2, 3], ([1, 2, 3], [4, 5, 6]), ([7, 8, 9], [10, 11, 12]))
ERROR: MethodError: no method matching fcn(::Array{Int64,1}, ::Tuple{Array{Int64,1},Array{Int64,1}}, ::Tuple{Array{Int64,1},Array{Int64,1}})
Closest candidates are:
  fcn(::AbstractArray{T,1}, ::Tuple{V}, ::Tuple{V}) where {T<:Real, V<:AbstractArray{T,1}} at REPL[39]:1
Stacktrace:
 [1] top-level scope at REPL[40]:1

Problem 1: You are over-typing your code :wink:

Problem 2:

julia> (2.1,) isa Tuple{Float64}
true

julia> (2.1,3.0) isa Tuple{Float64}
false

So Tuple{V} can only have a single element.

This works, but only for length-2 tuples:


function fcn(xvec::AbstractVector{T}, ytup::Tuple{V,V}, ztup::Tuple{V,V}) where {T <: Real, V <: AbstractVector{T}}
    @show typeof(xvec)
    @show typeof(ytup)
    @show typeof(ztup)
end

You also have a typo xVec -> xvec.

2 Likes

To make this example work as you intended, you probably want to use either Tuple{Vararg{V}}, or NTuple{N,V} where N, which will work for tuples of an arbitrary number of elements <:V.

4 Likes

Thank you both of you!

What about here?

function fcn(TupVecs::NTuple{N, V}) where {N, V <: AbstractVector}
	x = 1
	for nVec āˆˆ eachindex(TupVecs)
		y = TupVecs[nVec][2]
		println(y)
	end
end

function fcn(TupFcns::NTuple{N, F}) where {N, F <: Function}
	x = 1
	for nFcn āˆˆ eachindex(TupFcns)
		y = TupFcns[nFcn](x)
		println(y)
	end
end

TupVecs = (
	[1, 3, 5],
	[1, 4, 6, 9],
	[1, 5]
)

TupFcns = (
	x -> x^2,
	x -> x^3,
	x -> x^4
)

fcn(TupVecs) # works fine
fcn(TupFcns) # method error

Edit: Iā€™m going to stick with vectors of functions and vectors, instead of tuples of functions and vectors.