Thank you all for your responses!
Jeffrey -- Sorry that my wording wasn't clear. I don't want to extract the
sequence from the type, I just want to be able to dispatch based on the
sequence. My end goal is to have a function that computes a rotation
tensor from an Euler sequence, and I would need to have a different method
for each sequence, so it would be handy to be able to dispatch on it.
Tim -- I'm aware of the singularities. However, Euler angles are still
used extensively in Aerospace. For my purposes, the equations of motion
use a rotation tensor or quaternion internally, but Euler angles are easier
to visualize and are therefore more convenient for input and output.
Simon -- I'm not sure if I want the EulerAngles type to be mutable or
immutable. I definitely planned to look at the types you recommended as I
continue to tinker.
With Simon's suggested use of call, it looks like my first question (how to
make a constructor where only the sequence is manually specified) is
answered.
I guess my only remaining question at the moment is about design. There
seem to be several solutions that would all work. I'm not sure I
understand the benefits of one over the other. The options seem to be:
1) A type where the sequence is a member
type EulerAngles{T <: Number}
sequence::Int
angles::Vector{T}
end
function rotationtensor{T <: Number}(euler::EulerAngles{T})
if euler.sequence == 123
# ...
end
end
2) A type where the sequence is a type parameter
type EulerAngles{s, T <: Number}
angles::Vector{T}
end
function rotationtensor{T <: Number}(euler::EulerAngles{123, T})
# ...
end
3) A hierarchy of types where the sequence is part of the name of the
concrete types
abstract EulerAngles{T <: Number}
type EulerAngles123{T <: Number} <: EulerAngles{T}
angles::Vector{T}
end
function rotationtensor{T <: Number}(euler::EulerAngles123{T})
# ...
end