I have a record type like this one:
data VehicleState f = VehicleState
{
orientation :: f (Quaternion Double),
orientationRate :: f (Quaternion Double),
acceleration :: f (V3 (Acceleration Double)),
velocity :: f (V3 (Velocity Double)),
location :: f (Coordinate),
elapsedTime :: f (Time Double)
}
deriving (Show)
This is cool, because I can have a VehicleState Signal
where I have all sorts of metadata, I can have a VehicleState (Wire s e m ())
where I have the netwire
semantics of each signal, or I can have a VehicleState Identity
where I have actual values observed at a certain time.
Is there a good way to map back and forth between VehicleState Identity
and VehicleState'
, defined by mapping runIdentity
over each field?
data VehicleState' = VehicleState'
{
orientation :: Quaternion Double,
orientationRate :: Quaternion Double,
acceleration :: V3 (Acceleration Double),
velocity :: V3 (Velocity Double),
location :: Coordinate,
elapsedTime :: Time Double
}
deriving (Show)
Obviously it's trivial to write one, but I actually have several types like this in my real application and I keep adding or removing fields, so it is tedious.
I am writing some Template Haskell that does it, just wondering if I am reinventing the wheel.
If you're not opposed to type families and don't need too much type inference, you can actually get away with using a single datatype:
import Data.Singletons.Prelude
data Record f = Record
{ x :: Apply f Int
, y :: Apply f Bool
, z :: Apply f String
}
type Record' = Record IdSym0
test1 :: Record (TyCon1 Maybe)
test1 = Record (Just 3) Nothing (Just "foo")
test2 :: Record'
test2 = Record 2 False "bar"
The Apply
type family is defined in the singletons package. It can be applied to
various type functions also defined in that package (and of course, you can define your
own). The IdSym0
has the property that Apply IdSym0 x
reduces to plain x
. And
TyCon1
has the property that Apply (TyCon1 f) x
reduces to f x
.
As demonstrated by
test1
and test2
, this allows both versions of your datatype. However, you need
type annotations for most records now.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With