Haskell 如何使用数据。数据?

Haskell 如何使用数据。数据?,haskell,scrap-your-boilerplate,rank-n-types,Haskell,Scrap Your Boilerplate,Rank N Types,由于我不熟悉rank-N类型,gfoldl的类型签名对我来说很麻烦: gfoldl :: (forall d b. Data d => c (d -> b) -> d -> c b) -> (forall g. g -> c g) -> a -> c a 我能想到的唯一函数分别是\xsy->($y)xs和pure 其他功能,如gunfold和gmapT也有类似的问题。那么,它们的非平凡用途的显著例子是什么呢?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
我能想到的唯一函数分别是
\xsy->($y)xs
pure


其他功能,如
gunfold
gmapT
也有类似的问题。那么,它们的非平凡用途的显著例子是什么呢?

Data.Data
是名为“废弃样板”的通用元编程框架的一部分

  • Data.Data
    模块链接到该主题的研究出版物列表

  • 中充满了泛型转换的示例,请特别参阅

  • 过去有一个SYB维基(链接自
    Data.Data
    和SYB),但不幸的是,它现在似乎已经死了

  • 对于另一种示例,(我是作者)使用
    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)

网上应该有一个SYB(废弃你的样板)教程。甚至不止一个。我从这里开始,因为像
gfoldl
这样的相对低级的原语一开始是非常通用和难以理解的。此外,SYB可能不是学习秩-N类型的最简单方法。此外,SYB比GHC更难掌握。泛型(尽管可以说更优雅),所以,如果你想用它来自动生成实例,那么你最好使用泛型。@leftaroundabout我想
gfoldl
有一些GHC.Generics无法涵盖的功能。我不会说它更优雅;只是不同而已
Data.Data
有一种“非类型化”的感觉,是“深”的,而
GHC.Generics
有一种非常“类型化”的感觉(虽然比
Generics sop
小),是“浅”的。我的总体印象是,
Data.Data
主要是提供工具来方便AST操作,而
GHC.Generics
更多的是关于类默认值等等。