Is there a way to use a type signature that imposes that two arguments are the same subtype of an abstract type and also have the same parameter for some but not necessarily all parameters?
For example, the hypothetical method of bob
below should dispatch whenever the two arguments (1) are both subtypes of AbstractArray (2) have the same concrete type (e.g. both are SparseArray or both are Array) (3) have the same number of dimensions. But they may have different eltypes.
""" method 1"""
bob(x::A{T1, D} , y::A{T2, D} ) where {A <: AbstractArray, T1, T2, D} =
"same array type, same number of dimensions, possibly different eltypes"
The above throws an error (“TypeError: in Type{…} expression, expected UnionAll, got a value of type TypeVar”).
Methods that do not accomplish what I want, but are syntactically valid:
""" method 2"""
bob(x::AbstractArray{<:Any, D}, y::AbstractArray{<:Any, D}) where D =
"abstract arrays with same number of dimensions"
""" method 3"""
bob(x::T, y::T) where T <: AbstractArray =
"same subtype of abstract array"
""" method 4 """
bob(x::A, y::A) where A <: AbstractArray{T, D} where {T, D} =
"same parametric type"
A = SentinelVector{Float64}(undef, 10)
bob(A, [1,2]) # dispatches to method 2. I do not want it to dispatch to method 1
bob([1 2; 3 4], [1,2]) # dispatches to method 3. I do not want it to dispatch to method 1
bob([1.], [2.]) # would dispatch to method 4.
bob([1. 2.; 3. 4.], [1 2 3; 4 5 6]) # would want to dispatch to method 1.
# does not match type signature for method 4.
# matches type signature for method 2 and 3.
Is there a syntax for method 1 that actually works, or is there no way to directly accomplish my intent with a single method signature? (note, I am not actually doing this for AbstractArray but for a user-defined type. The reason I am doing this is because if method 1 matches, then I can skip to directly doing a thing, but if method 1 does not match, then I want to do a bunch of checks before doing the thing, accomplished by bob(x, y) = "do checks"
.
There are obvious workarounds – I could, for example, check in the function body for the conditions, but it seems like I should be able to directly and more parsimoniously accomplish this with a type signature.