Why doesn't an argument of Vector{Vector{T} where T<:Real} accept a variable of Vector{Vector{Int64}}?


#1

Why does the function f3 below fail, while the functions f1 and f2 succeed?
(Jupyter 0.6.2.2, JuliaPro 0.6.2.2)

function f3(a::Vector{Vector{T} where T<:Real})
2a
end

a = Vector{Vector}(3)
for i in 1:3
a[i] = [i, i+ 1]
end

f3(a)
MethodError: no method matching f3(::Array{Array{T,1} where T,1})
Closest candidates are:
f3(::Array{Array{T,1} where T<:Real,1}) at In[7]:2

function f1(a::Vector{Vector})
2a
end

function f2(a::Vector{Vector{T} where T})
3a
end


#2

Because your a is not a subtype of Vector{Vector{<:Real}} (which is a shorthand for what you write):

julia> a = Vector{Vector}(3);

julia> for i in 1:3
       a[i] = [i, i+ 1]
       end;

julia> a
3-element Array{Array{T,1} where T,1}:
 [1, 2]
 [2, 3]
 [3, 4]

However, this does not work either:

julia> a = Vector{Vector{Int}}(3);

julia> for i in 1:3
       a[i] = [i, i+ 1]
       end;

julia> a
3-element Array{Array{Int64,1},1}:
 [1, 2]
 [2, 3]
 [3, 4]

julia> f3(a)
ERROR: MethodError: no method matching f3(::Array{Array{Int64,1},1})
Closest candidates are:
  f3(::Array{Array{T,1} where T<:Real,1}) at REPL[1]:2

This finally works:

julia> a = Vector{Vector{<:Real}}(3);

julia> for i in 1:3
       a[i] = [i, i+ 1]
       end;

julia> a
3-element Array{Array{T,1} where T<:Real,1}:
 [1, 2]
 [2, 3]
 [3, 4]

julia> f3(a)
3-element Array{Array{Int64,1},1}:
 [2, 4]
 [4, 6]
 [6, 8]

However, what you probably wanted to do was:

function f3(a::Vector{Vector{T}}) where T<:Real
2a
end

then all of the above a will work. Search the docs or this forum for “invariance” to find enlightenment (although, it is a bit a tricky subject).

PS: please quote your code snippets using backticks `: PSA: how to quote code with backticks


#3

Great! Thank you :smiley:
I tried it as follows, and it worked:

function f4(a::Vector{Vector{T}}) where T<:Real
    4a
end

a = Vector{Vector{Real}}(3)
for i in 1:3
    a[i] = [i, i+ 1]
end

f4(a)

results in

3-element Array{Array{Int64,1},1}:
 [4, 8]  
 [8, 12] 
 [12, 16]

Thanks for the tip, too.