[Haskell-cafe] Layer on a layer of record syntax in the type synonym?

Christopher Howard christopher.howard at frigidcode.com
Fri Dec 21 22:50:02 CET 2012


On 12/21/2012 04:52 AM, Daniel Trstenjak wrote:
> 
> Why having a Socket3 in the first place, what's the point of it?
> 

The idea was to have some generic structures (Sockets) which were
already instanced into the Monoids-within-Monoids abstraction, yet could
still be made concrete into anything more specific.

So, I have...

code:
--------
data Socket3 a b c = Socket3 a b c
  deriving (Show)

instance (Monoid a, Monoid b, Monoid c) => Monoid (Socket3 a b c) where
    mempty = Socket3 mempty mempty mempty
    Socket3 a b c `mappend` Socket3 w x y =
        Socket3 (a <> w) (b <> x) (c <> y)

nullSocket3 :: (Monoid a, Monoid b, Monoid c) => Socket3 a b c
nullSocket3 = Socket3 mempty mempty mempty
--------

...which allows me to have...

code:
--------
type ShipSys = Socket3 (Last Engine) (Last RotThruster) [LinThruster]

nullShipSys :: ShipSys
nullShipSys = nullSocket3

setEngineSocket (Socket3 a b c) x = Socket3 x b c

engineSys :: Engine -> ShipSys
engineSys a = setEngineSocket nullShipSys (Last (Just a))

mk1Engine = engineSys (Engine 100 1 "Mark I")

-- etc.
--------

And so, with each individual component being wrapped as a generic
ShipSys (ship system), I can make a complete system simply by composition:

code:
--------
h> :t mk1Engine
mk1Engine :: ShipSys
h> :t stdRearThruster
stdRearThruster :: ShipSys
h> :t stdFrontThruster
stdFrontThruster :: ShipSys
h> :t stdRotThruster
stdRotThruster :: Power -> ShipSys
h> mk1Engine <> stdRearThruster <> stdFrontThruster <> stdRotThruster 10
Socket3 (Last {getLast = Just (Engine 100.0 1.0 "Mark I")}) (Last
{getLast = Just (RotThruster 10.0)}) [LinThruster 3.1415927
1.0,LinThruster 0.0 0.5]
--------

This seems to work well enough so far. But the issue I was concerned
about is: if I can't layer record syntax onto the type synonym, then I
have to rewrite a whole bunch of getters / setters each time I want to
add an attribute (e.g., requiring a switch from a Socket3 to a Socket4.)
If this is the case, then perhaps it would be better just to define the
ShipSys type directly, and directly instance it into the monoid abstraction.

-- 
frigidcode.com

-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 553 bytes
Desc: OpenPGP digital signature
URL: <http://www.haskell.org/pipermail/haskell-cafe/attachments/20121221/3a2c48f7/attachment-0001.pgp>


More information about the Haskell-Cafe mailing list