packages feed

syb-0.3.6: tests/NestedDatatypes.hs

{-# OPTIONS -fglasgow-exts #-}
{-# LANGUAGE UndecidableInstances #-}

module NestedDatatypes () where

{-

We provide an illustrative ScrapYourBoilerplate example for a nested
datatype.  For clarity, we do not derive the Typeable and Data
instances by the deriving mechanism but we show the intended
definitions. The overall conclusion is that nested datatypes do not
pose any challenge for the ScrapYourBoilerplate scheme. Well, this is
maybe not quite true because it seems like we need to allow
undecidable instances.

-}

import Data.Dynamic
import Data.Generics

 
-- A nested datatype
data Nest a = Box a | Wrap (Nest [a])


-- The representation of the type constructor    
nestTc = mkTyCon "Nest"


-- The Typeable instance for the nested datatype    
instance Typeable1 Nest
  where
    typeOf1 n = mkTyConApp nestTc []


-- The Data instance for the nested datatype
instance (Data a, Data [a]) => Data (Nest a)
  where
    gfoldl k z (Box a)  = z Box `k` a
    gfoldl k z (Wrap w) = z Wrap `k` w
    gmapT f (Box a)  = Box (f a)
    gmapT f (Wrap w) = Wrap (f w)
    toConstr (Box _)  = boxConstr
    toConstr (Wrap _) = wrapConstr
    gunfold k z c = case constrIndex c of
                      1 -> k (z Box)
                      2 -> k (z Wrap)
    dataTypeOf _ = nestDataType

boxConstr    = mkConstr nestDataType "Box"  [] Prefix
wrapConstr   = mkConstr nestDataType "Wrap" [] Prefix
nestDataType = mkDataType "Main.Nest" [boxConstr,wrapConstr]