I have a struct that I would like to consist of only Array or CuArray, but I would like a mix of different kinds to throw. I can enforce uniform types by using the {T}, but how do I define my struct to make the vel_mix construction throw an error?

using CUDA
struct Velocity{T}
u::AbstractArray{T, 2}
v::AbstractArray{T, 2}
end
u = zeros(3, 3); v = zeros(3, 3)
vel_cpu = Velocity(u, v) # OK
vel_gpu = Velocity(CuArray(u), CuArray(v)) # OK
vel_mix = Velocity(CuArray(u), v) # I would like this one to throw.

I may be wrong but I think youâ€™ll need to use a constructor to enforce the dimensions. I donâ€™t think you can express the relationship of â€śone dimension lessâ€ť (because you canâ€™t do math on the type) in the type system (but please someone prove me wrong if it is possible).

My question wasnâ€™t well formulated. What I meant to ask was: what if I mix different dimension sizes, can I define the struct such that all arrays are of the same kind, irrespective of their nmber of dimensions, or do I need a constructor for that?

For instance

struct Velocity{T, U2 <: AbstractArray{T, 2}, U1 <: AbstractArray{T, 1}}
u::U2
v::U2
z::U1
end

would not solve it, because it allows U1 to be an Array and U2 a CuArray.