1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44
|
{-# LANGUAGE DeriveDataTypeable #-}
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE MonoLocalBinds #-}
{-# 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]) deriving Typeable
-- 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]
|