Thank you all, In fact, Brandon, I knew about Datatypes a la carte, I just found it overly complicated.
Thanks for you solution, Job. However (and even if it doesn't work without it) I fail to see why you need the functional dependency on Has... Doesn't it implies here that for one 'a' there can only be one 'b' such as 'Has b a'? 2011/4/6 Job Vranish <[email protected]> > I think you want something like this: > > {-# Language MultiParamTypeClasses > , FlexibleInstances > , FunctionalDependencies > , UndecidableInstances > , FlexibleContexts > , OverlappingInstances > > #-} > data Character a = Character { life :: Int, > charaInner :: a } > deriving (Show) > > data Gun a = Gun { firepower :: Int, > gunInner :: a } > deriving (Show) > > data Armor a = Armor { resistance :: Int, > armorInner :: a } > deriving (Show) > > > class HasInner f where > getInner :: f a -> a > > instance HasInner Character where > getInner = charaInner > > instance HasInner Gun where > getInner = gunInner > > instance HasInner Armor where > getInner = armorInner > > > class Has b a | a -> b where > content :: a -> b > > instance (Has b a, HasInner f) => Has b (f a) where > content a = content $ getInner a > > instance (HasInner f) => Has a (f a) where > content a = getInner a > > chara = Character 100 $ Armor 40 $ Gun 12 () > > itsGun :: (Has (Gun b) a) => a -> Gun b > itsGun = content > > You were missing a mechanism to extract the inner value from your > datatypes. > > - Job > > > On Wed, Apr 6, 2011 at 2:57 PM, Yves Parès <[email protected]> wrote: > >> Hello Café, >> >> I'm trying to get some modular data types. >> The idea that came to me is that I could stack them, for instance : >> >> data Character a = Character { life :: Int, >> charaInner :: a } >> >> data Gun a = Gun { firepower :: Int, >> gunInner :: a } >> >> data Armor a = Armor { resistance :: Int, >> armorInner :: a } >> >> Then a character with a gun and an armor can be build this way: >> >> chara = Character 100 $ Armor 40 $ Gun 12 >> >> The idea now is to be able to get some part of the character: >> >> itsGun :: Character ?? -> Gun ?? >> itsGun = content >> >> Then content would be a class method: >> >> class Has b a where >> content :: a -> b >> >> And it would be recursively defined so that: >> >> instance (Has c b, Has b a) => Has c a where >> content = (content :: b -> c) . (content :: a -> b) >> >> Then itsGun would be more like: >> >> itsGun :: (Has Gun a) => a -> Gun ?? >> itsGun = content >> >> But after some juggling with extensions (ScopedTypeVariables, >> UndecidableInstances, IncoherentInstances...) I can't get it working. >> >> Has someone a simpler way to achieve modular types? >> >> _______________________________________________ >> 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
