2

由于我不熟悉 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也有类似问题。那么它们的重要用途有哪些值得注意的例子呢?

4

2 回答 2

3

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

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

例如,要增加int中的所有字段A,您可以编写类似

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)
于 2019-08-07T14:28:01.500 回答
0

Data.Data是名为“Scrap your Boilerplate”的通用元编程框架的一部分。

于 2019-08-07T14:20:39.880 回答