简体   繁体   中英

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?

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)

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM