How to use Data.Data?

494 views Asked by At

As I'm not familiar with rank-N types, the type signature of gfoldl is a troublesome for me:

gfoldl :: (forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g)
-> a
-> c a

The only functions I can think of are \xs y -> ($y) <$> xs and pure, respectively.

Other functions such as gunfold and gmapT have similar problems. So what are notable examples of nontrivial uses of them?

2

There are 2 answers

0
ekim boran On BEST ANSWER

For the gmapT case the mkT function is defined for this purpose in the original paper.

mkT :: (Typeable a, Typeable b ) => (b -> b) -> a -> a
mkT f = fromMaybe id (cast f)

For example to increment all int fields in the A, you can write something like

data A = A {f :: Int, s :: Int} deriving (Data, Typeable)

ex = gmapT (mkT inc) (A 2 3) where 
  inc :: Int -> Int
  inc = (+1)

To make it clearer the ex function can be written like this too:

ex2 = gmapT f (A 2 3) where 
  f :: (Data a ) =>  a -> a
  f a = case cast a of 
    Nothing -> a
    (Just (b :: Int)) -> fromJust $ cast (b + 1)
0
Li-yao Xia On

Data.Data is part of a generic metaprogramming framework called "Scrap your boilerplate".