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 <[email protected]> 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 > [email protected] > http://www.haskell.org/mailman/listinfo/haskell-cafe > _______________________________________________ Haskell-Cafe mailing list [email protected] http://www.haskell.org/mailman/listinfo/haskell-cafe
