# Difference between vector and vector of vectors

My function `f(x::Vector)` works on a vector of numbers (e.g. `x=[0.1, 0.2]`).

However, I’d like to create another method for vector of vectors (e.g. `x=[[0.1, 0.2], [0.3, 0.4]]`), which uses the vector-of-numbers version.

However, it seems that `x=[0.1, 0.2]` and `x=[[0.1, 0.2], [0.3, 0.4]]` are of the same type: the vector-of-vectors is caught and processed by the first version.

How can I specify vector-of-vectors and vector-of-numbers as types to dispatch on? Thank you!

I’d recommend using broadcasting in this case: that’s just `f.([[0.1, 0.2], [0.3, 0.4]])`. Broadcasting works element-wise across the container you pass it, without needing to define an additional method.

A vector of vectors is indeed just a vector. The difference is in its element type:

``````f(x::Vector{<:Number}) = "vector of numbers"
f(x::Vector{<:Vector}) = "vector of vectors"
julia> f([1,2,3])
"vector of numbers"

julia> f([[1,2],[3,4]])
"vector of vectors"
``````

But note that this isn’t the same as saying what they contain — it’s just a property of the vector itself. In fact, you can have vectors that contain just numbers and won’t work with the above, because they can contain `Any`thing:

``````julia> f(Any[1,2,3])
ERROR: MethodError: no method matching f(::Array{Any,1})
Closest candidates are:
f(::Array{#s1,1} where #s1<:Real) at REPL[10]:1
f(::Array{#s1,1} where #s1<:(Array{T,1} where T)) at REPL[10]:2
Stacktrace:
[1] top-level scope at none:0
``````
4 Likes

Awesome, thanks for that comprehensive reply!

I would just add a change to the type notation as my preferred one,
if you wanted to allow a more flexible approach which I don’t particularly recommend,

``````f(obj::AbstractVector) = all(elem isa Number for elem ∈ obj) ?
f(convert(Vector{reduce(promote_type, typeof(elem) for elem ∈ obj)}, obj)) :
throw(ArgumentError("elements should all be numbers"))
f(::AbstractVector{<:Number}) = ...
``````

I would just keep the second one.