私はLanguage.Exts.Annotated.Syntaxからの値を処理するコードを書いています。ここでは、Haskellモジュールの構造を反映するさまざまなタイプが定義されています。
data Module l = ...
data Decl l = ...
data Exp t = ...
-- etc
これらのデータ構造をウォークし、さまざまな変換を実行する関数を記述できるようにしたいと思います。共通のデータ型が1つもないため、すべてを実行する1つの関数を作成することはできません。
これまでのところTree
、変換関数が実行できるように、これらの各型をラップする型を作成しましたTree l -> Tree l
。
data Tree l = ModuleT (Module l)
| DeclT (Decl l)
| ExpT (Exp l)
-- etc copy & paste
しかし、私は今、を取り、Module
それをラップしModuleT
、関数を呼び出し、そして結果をModule
再びアンラップする多くのコードを書いていることに気づいています。私は持っています:
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
2つの質問:
- Language.Exts.Annotated.Syntaxの型を変更できないことを考えると、これは間違った方法で行っているのでしょうか。
- そうでない場合は、この定型文をなんとかして削減できますか?