How to dispatch like f(::AbstractArray{T1,N+1}, ::AbstractArray{T2,N})?

Is it possible to dispatch on the difference between the dimensions of two arrays arguments? One can, for example, define

f(::AbstractArray{T1,N}, ::AbstractArray{T2,N}) where {T1,T2,N} = ...

Then, this method will be called when the arguments are arrays of the same dimensionality.

On the other hand, I’d like to have a method that applies to the case when one array, say the first, has exactly one more dimension, when compared to the second one, that is, I’d like to define something like

f(::AbstractArray{T1,N+1}, ::AbstractArray{T2,N}) where {T1,T2,N} = ...

but this throws an error:

ERROR: MethodError: no method matching +(::TypeVar, ::Int64)

I conclude that, in this context, N is not an Int, but a TypeVar. Still, would there be another way to accomplish this?

As far as I know the best you can do is to have separate dimensionality parameters and check their relation in other ways. Although you can do something like this to mostly keep it within dispatch:

f(x::AbstractArray{T1,N1}, y::AbstractArray{T2,N2}) where {T1,T2,N1,N2} = f(x, y, Val(N1 - N2))
f(x::AbstractArray{T1,N1}, y::AbstractArray{T2,N2}, ::Val{1}) where {T1,T2,N1,N2} = ...
4 Likes

This sort of type computation isn’t possible in argument annotations because + is a modifiable generic function and N has an unknowable type (also applies to struct field annotations with different complications). We pretty much always use N::Int for AbstractArray and we’d never change what integer addition does, but the language has no idea. As far as it knows, I could define + to return the first input for an exotic N, then you get a weird ambiguity with f(::AbstractArray{T1,N}, ::AbstractArray{T2,N}) where {T1,T2,N} = ....
Related type parameters thus have to be annotated independently at first and validated elsewhere. @assert statements comparing static parameters can be written in the method body and can be easily computed at compile-time. The Holy trait-like pattern above lets you write multiple methods for various relations.

1 Like