我一直在摆弄用 Haskell 编写的 Elm 编译器。
我想开始对其进行一些优化,其中一部分涉及遍历 AST 并向某些节点添加“注释”,例如尾调用等。
我知道我可以使用 SYB 或 uniplate 进行遍历,但我想知道是否有一种无样板的方式来处理这些类型。
所以,假设我们的 AST 有一堆代数类型:
data Expr = PlusExpr Expr Expr ...
data Def = TypeAlias String [String] Type ...
如果我正在编写样板文件,我会创建这样的新类型:
data AnnotatedExpr = PlusExpr Expr Expr [Annotation] ...
data AnnotatedDef = TypeAlias String [String] Type [Annotation] ...
这是要编写的大量样板代码,避免这种情况似乎是一种好习惯。
我可以写这样的东西:
Data AnnotationTree = Leaf [Annotation]
| Internal [AnnotationTree] [Annotation]
然后我就会有一个与 AST 并行运行的注释树。但是不能保证这些树会有相同的结构,所以我们失去了类型安全。
所以我想知道,是否有一种优雅/推荐的解决方案来避免样板,但仍然以类型安全的方式注释树?用等效的节点替换每个节点,加上稍后将在编译中使用的注释列表?