Haskell 如何使用数据。数据?
由于我不熟悉rank-N类型,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是名为“废弃样板”的
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维基(链接自
和SYB),但不幸的是,它现在似乎已经死了Data.Data
- 对于另一种示例,(我是作者)使用
作为具有某些一致性属性的通用随机生成器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
更多的是关于类默认值等等。