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`