What are you trying to dispatch on?
It sounds like you mean to dispatch for
julia> t = (0, 0, 0, 0)
(0, 0, 0, 0)
julia> typeof(t)
NTuple{4, Int64}
julia> Tuple{Int, Int, Int, Int} == NTuple{4, Int}
true
As shown above the type of t
is NTuple{4, Int64}
, not NTuple{4, Val{0}}
. For that we would need the following.
julia> t2 = Val.((0,0,0,0))
(Val{0}(), Val{0}(), Val{0}(), Val{0}())
julia> typeof(t2)
NTuple{4, Val{0}}
Then we could do dispatch as follows.
julia> foo(a::AbstractArray{T,N}) where {N, T <: NTuple{N,Val{0}}} = 5
foo (generic function with 1 method)
julia> foo([t2 ;;;;])
5
If you wanted a more flexible version where T
could be an NTuple
with any number of Val(0)
, you could do
julia> foo(a::AbstractArray{T,N}) where {N, N2, T <: NTuple{N2,Val{0}}} = N2
foo (generic function with 2 methods)
julia> foo([Val.((0,)) ;;;;])
1
julia> foo([Val.((0,0)) ;;;;])
2
julia> foo([Val.((0,0,0)) ;;;;])
3
However, my suspicion is that you really want to dispatch on something like (0,0,0,0)
. We can do this with two definitions. The first checks the array to make sure it consists of tuples of a single value.
julia> foo(a::AbstractArray{T,N}) where {N, T <: NTuple{N}} = foo(a, Val(only(unique(only(unique(a))))))
foo (generic function with 4 methods)
julia> foo(a::AbstractArray{T,N}, ::Val{0}) where {N, T <: NTuple{N}} = println("This $(N)D array is filled with $N-Tuples filled with zeros")
foo (generic function with 4 methods)
julia> foo([ (0,) ])
This 1D array is filled with 1-Tuples filled with zeros
julia> foo([ (0,0) ;; ])
This 2D array is filled with 2-Tuples filled with zeros
julia> foo([ (0,0,0) ;;; ])
This 3D array is filled with 3-Tuples filled with zeros
julia> foo([ (0,0,0,0) ;;;; ])
This 4D array is filled with 4-Tuples filled with zeros
julia> foo([ (0,0,0) ;;;; ])
ERROR: MethodError: no method matching foo(::Array{Tuple{Int64, Int64, Int64}, 4})
julia> foo([ (0,0,0,1) ;;;; ])
ERROR: ArgumentError: Collection has multiple elements, must contain exactly 1 element
julia> foo([ (1,1,1,1) ;;;; ])
ERROR: MethodError: no method matching foo(::Array{NTuple{4, Int64}, 4}, ::Val{1})
Honestly though, you probably should just write an if
statement rather than using multiple dispatch to do this.