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.