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

Antoine Latter aslatter at gmail.com
Mon Dec 24 05:31:28 CET 2012


You could look into the "Generic Monoid" solution proposed in your
other thread, then you wouldn't need your "Socket" types  - you would
use the "Generic Monoid" machinery to make a Monoid instance for
whatever type needed it.

This approach loses some type-safety, as you might pass on version of
a Scoket3 to a function that was meant to take a different type of
Socket3.

On Fri, Dec 21, 2012 at 4:50 PM, Christopher Howard
<christopher.howard at frigidcode.com> wrote:
> 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
>
>
> _______________________________________________
> Haskell-Cafe mailing list
> Haskell-Cafe at haskell.org
> http://www.haskell.org/mailman/listinfo/haskell-cafe
>



More information about the Haskell-Cafe mailing list