Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to use Data.Data?

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?

like image 275
Dannyu NDos Avatar asked Oct 21 '25 03:10

Dannyu NDos


1 Answers

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)
like image 145
ekim boran Avatar answered Oct 24 '25 02:10

ekim boran