RE: container for different types, avoiding boiler plate
I use my 'DynamicMap' type to handle this sort of thing. However, I don't really recommend this approach unless you're very careful. You basically lose out on all nice type checking properties and enter a world of dynamic typing (more or less). Anyway, you can find it at: http://www.isi.edu/~hdaume/DynamicMap.hs it uses "NLP.FiniteMap", but you can replace this with "Data.FiniteMap". You can then do things like: data Gender = Masc | Fem | Neutr deriving Typeable data Number = First | Second | Third deriving Typeable let dm = addToDM (addToDM emptyDM Masc) Second case lookupDM dm of Just Masc -> "is a guy" Just _ -> "is not a guy" _ -> "i don't know gender" case lookupDM dm of Just First -> "is first" Just Second -> "is second" _ -> "either i don't know or is third" of course 'deriving Typeable' means you need GHC6; otherwise you can write the instances by hand. -- Hal Daume III | hdaume@isi.edu "Arrest this man, he talks in maths." | www.isi.edu/~hdaume
-----Original Message----- From: haskell-admin@haskell.org [mailto:haskell-admin@haskell.org] On Behalf Of Markus.Schnell@infineon.com Sent: Wednesday, August 20, 2003 5:01 AM To: haskell@haskell.org Subject: container for different types, avoiding boiler plate
I think similar things have been asked before, but I couldn't find anything specific. I have a data type with attributes. These attributes have different types. Right now I'm using a lot of boilerplate like that:
data Gender = Masc | Fem | Neutr ... data Attr = Gender Gender | Cat Cat | Graph Graph | ... data Type = TypeCat | TypeGender | ... deriving Eq
myTypeOf (Gender _) = TypeGender myTypeOf (Cat _) = TypeCat ... myTypeOf _ = TypeError
data Segment = Seg { attrs :: [Attr] }
attr f seg = seg { attrs = f (attrs seg) }
gattr :: Type -> [Attr] -> Maybe Attr gattr theType [] = fail "attribute not found" gattr theType (a:as) = if myTypeOf a == theType then return a else gattr theType as
cat :: Cat -> Segment -> Segment cat c = attr ((Cat c):) -- set value
gcat :: Segment -> Maybe Cat -- get value gcat = deCat . gattr TypeCat . attrs where deCat (Just (Cat c)) = c deCat x = x ...
Does anyone have some suggestions for making this more concise? Generic Haskell? Tricky type classes?
Thanks, Markus
-- Markus Schnell Infineon Technologies AG, CPR ET Tel +49 (89) 234-20875
_______________________________________________ Haskell mailing list Haskell@haskell.org http://www.haskell.org/mailman/listinfo/haskell
On Wed, 20 Aug 2003 08:25:39 -0700 "Hal Daume" <t-hald@microsoft.com> wrote:
I use my 'DynamicMap' type to handle this sort of thing. However, I don't really recommend this approach unless you're very careful. You basically lose out on all nice type checking properties and enter a world of dynamic typing (more or less).
Anyway, you can find it at:
http://www.isi.edu/~hdaume/DynamicMap.hs
it uses "NLP.FiniteMap", but you can replace this with "Data.FiniteMap".
You can then do things like:
data Gender = Masc | Fem | Neutr deriving Typeable data Number = First | Second | Third deriving Typeable
let dm = addToDM (addToDM emptyDM Masc) Second
case lookupDM dm of Just Masc -> "is a guy" Just _ -> "is not a guy" _ -> "i don't know gender"
case lookupDM dm of Just First -> "is first" Just Second -> "is second" _ -> "either i don't know or is third"
of course 'deriving Typeable' means you need GHC6; otherwise you can write the instances by hand.
One useful thing I've found when using Dynamics is that pattern guards can be used as a relatively compact typecase. E.g. foo dyn | Just b <- fromDynamic dyn = if b then "T" else "F" | Just (s :: String) <- fromDynamic dyn = show s | otherwise = show dyn The only other way I could think of getting typecase like behavior at another time before I knew about pattern guards was through a horrendous set of nested case statements. Another trick for debugging is it is fairly easy to get Haskell to know the "expected" type, so that you can have error messages, in a generic error handling routine, like, "expected Int but got <<FooBar>>".
participants (2)
-
Derek Elkins -
Hal Daume