由于我不熟悉 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) <$> xs
和pure
,分别。
其他功能如gunfold
和gmapT
也有类似问题。那么它们的重要用途有哪些值得注意的例子呢?
由于我不熟悉 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) <$> xs
和pure
,分别。
其他功能如gunfold
和gmapT
也有类似问题。那么它们的重要用途有哪些值得注意的例子呢?
对于这种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)
Data.Data
是名为“Scrap your Boilerplate”的通用元编程框架的一部分。
该Data.Data
模块链接到有关该主题的研究出版物列表https://wiki.haskell.org/Research_papers/Generics#Scrap_your_boilerplate.21
曾经有一个 SYB wiki(链接自Data.Data
和 syb),但遗憾的是它现在似乎已经死了。
对于另一种示例,boltzmann-samplers(我是作者)Data.Data
用于具有一些均匀性属性的通用随机生成器。