I have a type that represents a direction, it has an axis and an orientation:
data Dir = DirX | DirY | DirZ | DirW deriving (Show, Eq)
data Sign = Pos | Neg deriving (Show, Eq)
newtype Direction = Direction (Dir, Sign) deriving (Show, Eq)
And that looks kinda overcomplicated. I don't need Sign
and Dir
to be distinct types, I just want to pattern match things to their constructors. So is there any nicer way to define such kind of types?
So what I want to do is some kind of
data Direction = Direction (DirX | DirY | DirZ | DirW) (Pos | Neg) deriving (Show, Eq)
Because I do things like \(Direction _ s) -> if s == Pos then ... else ...
, but I never use Dir
or Sign
outside of the Direction
I suppose I'm not the first one to ask this, but I really can't figure out how to google this question.
Nope, there's no nicer way.
...then again, personally, I find this way perfectly nice already. So perhaps it is not such a terrible burden to bear.
Of course, there are ways to define completely different types that might still be of interest to you. For example, I have used a direction type along these lines in the past to good effect:
data Direction = Direction { x, y, z, w :: Int }
aboutFace (Direction x y z w) = Direction (-x) (-y) (-z) (-w)
-- e is a traditional name from linear algebra for an axis-aligned unit vector
ex = Direction 1 0 0 0
ey = Direction 0 1 0 0
ez = Direction 0 0 1 0
ew = Direction 0 0 0 1