I want to describe two kinds of state vectors: CartesianState and KeplerianState. For convenience, I’d like to have these state vectors to be mutable and have labels via LabelledArrays.
Now, I’d like to be able to use methods which work for all state vector types. Without type parameters, I’d like to define abstract type AbstractState end, and have CartesianState and KeplerianState be aliases for LArray.
I understand I can’t have the best of both worlds – to have two new aliases which are also subtypes of a new abstract type, we’d have to insert a supertype above LArray, which is definitely not okay.
My question is – what’s the closest we can come to accomplishing this?
I have two options below, though I’m not sure how advisable they are. I was curious what other folks’ go-to method for this would be. One issue I see with Option 2 is if users make their own NewState type, it wouldn’t be dispatch-able because the Union is already defined.
Option 1
The abstract type is an alias.
# LArray's parameters are {eltype, dimension, vector type, tuple with labels}
const AbstractState{F, V, L} = LArray{F, 1, V, L} # always a vector
const CartesianState{F, V} = AbstractState{F, V, (x=1, y=2, z=3, ẋ=4, ẏ=5, ż=6, r=1:3, v=4:6)}
const KeplerianState{F, V} = AbstractState{F, V, (e=1, a=2, i=3, Ω=4, ω=5, ν=6)}
f(x::AbstractState) = typeof(x) # should dispatch on `CartesianState` or `KeplerianState`
Option 2
The abstract type is a Union.
# LArray's parameters are {eltype, dimension, vector type, tuple with labels}
const CartesianState{F, V} = LArray{F, 1, V, (x=1, y=2, z=3, ẋ=4, ẏ=5, ż=6, r=1:3, v=4:6)}
const KeplerianState{F, V} = LArray{F, 1, V, (e=1, a=2, i=3, Ω=4, ω=5, ν=6)}
const AbstractState = Union{CartesianState, KeplerianState}
f(x<:AbstractState) = typeof(x) # should dispatch on `CartesianState` or `KeplerianState`