如何使用Data.Data?

How to use Data.Data?

由于我不熟悉rank-N类型,gfoldl的类型签名对我来说很麻烦:

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

我能想到的功能只有\xs y -> ($y) <$> xspure

其他函数如gunfoldgmapT也有类似的问题。那么它们的重要用途有哪些值得注意的例子?

Data.Data 是名为 "Scrap your boilerplate".

的通用元编程框架的一部分

对于 gmapT 的情况,mkT 函数是在原始论文中为此目的定义的。

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

例如,要递增 A 中的所有 int 字段,您可以这样写

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

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

为了更清楚,ex 函数也可以这样写:

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)