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