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 Data.Data
module links to a list of research publications on the topic https://wiki.haskell.org/Research_papers/Generics#Scrap_your_boilerplate.21
The syb library is full of examples of generic transformations, see in particular the Schemes module
There used to be a SYB wiki (linked from Data.Data
and syb) but sadly it seems dead now.
For a different kind of example, boltzmann-samplers (I'm the author) uses Data.Data
for generic random generators with some uniformity properties.
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.