I want to make a struct where the second parameter used represents the dimensionality of the world, with scalar fields being N-dimensional arrays and vector fields being (N + 1)-dimensional arrays. Something like this:
struct Domain{T, N}
scalar_fields::Array{T, N}
vector_fields::Array{T, N + 1}
end
dom = Domain{Float64, 2}(zeros(Float64, 10, 10), zeros(Float64, 10, 10, 10))
This is not allowed since the + operation in being done within the struct definition with N is still a TypeVar, giving the error:
ERROR: MethodError: no method matching +(::TypeVar, ::Int64)
I am aware this could be technically accomplished by just omitting the dimension of the Array in the vector_fields definition and enforcing its dimension through a constructor but since Array{Float64} is not a concrete type, I’d rather not pay the performance cost and just hardcode it if it’s not possible.
I think the only way to do this to use another parameter,
struct Domain{T, N, M}
scalar_fields::Array{T, N}
vector_fields::Array{T, M}
end
and only use it for M == N+1. You could add this as a test inside a constructor. Such a test would be evaluated at compile-time, so that it doesn’t incur a runtime penalty.
From one of the “Related” threads that Discourse suggested below here:
Still uses an extra type parameter, but the constructor definition neatly makes it so that the redundant parameter doesn’t have to be explicitly given during struct instance initialization.