我正在编写处理来自
Language.Exts.Annotated.Syntax
,其中定义了反映haskell模块结构的各种类型:
data Module l = ...
data Decl l = ...
data Exp t = ...
-- etc
我希望能够编写遍历这些数据结构并对其执行各种转换的函数。因为没有一个通用的数据类型,所以我不能编写一个可以完成所有工作的函数。
到目前为止,我已经写了一篇
Tree
包装每种类型的类型,以便我的转换函数可以
Tree l -> Tree l
:
data Tree l = ModuleT (Module l)
| DeclT (Decl l)
| ExpT (Exp l)
-- etc copy & paste
然而,我发现自己写了很多代码,需要
Module
包装它
ModuleT
,调用一个函数,然后将结果展开回
模块
再一次。我有:
class AnnotatedTree ast where
tree :: ast l -> Tree l
untree :: Tree l -> ast l
instance AnnotatedTree Module where
tree = ModuleT
untree (ModuleT x) = x
untree _ = error "expected ModuleT"
-- etc ad nauseam
两个问题:
-
考虑到我不能更改language.exts.annotated.syntax中的类型,我这样做是错误的吗?
-
如果不是的话,我能把所有这些样板文件都砍掉吗?