container for different types, avoiding boiler plate

Markus.Schnell@infineon.com Markus.Schnell@infineon.com
Wed, 20 Aug 2003 14:01:23 +0200


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