Why is it not matching NTuple{N,T} when specifying N

Consider the following code:

julia> f1(x::NTuple{N,T}) where {N, T<:Number} = "ok"
f1 (generic function with 1 method)

julia> f1((1,2,3))
"ok"

However, when I specifying N to be an integer as following:

julia> f2(x::NTuple{N,T}) where {N<:Integer, T<:Number} = "not work"
f2 (generic function with 1 method)

julia> f2((1,2,3))
ERROR: MethodError: no method matching f2(::Tuple{Int64,Int64,Int64})
Closest candidates are:
  f2(::Tuple{Vararg{T<:Number,N<:Integer}}) where {N<:Integer, T<:Number} at REPL[3]:1
Stacktrace:
 [1] top-level scope at none:0

Why would Tuple{Int64,Int64,Int64} not match NTuple{N,T} where {N<:Integer, T<:Number} here?

1 Like

When you specify N<:Integer, what you are actually telling Julia is not “N is an Integer”, instead you are saying, “N is a type which is a subtype of Integer”. However, you do not want N to be a type, but a number. There is currently no way to specify this: https://github.com/JuliaLang/julia/issues/9580.

7 Likes

To illustrate the difference a bit more, note that if this was ever allowed, the notation would probably be something like this: (:: vs. <:)

f2(x::NTuple{N,T}) where {N::Integer, T<:Number}
1 Like