在Haskell中編寫編譯器時,我在處理嵌套數據類型時偶爾遇到了一些特定問題。我將有一個ADT定義類似使用其他數據在Haskell中註釋嵌套ADT
data AST = AST [GlobalDecl]
data GlobalDecl = Func Type Identifier [Stmt] | ...
data Stmt = Assign Identifier Exp | ...
data Exp = Var Identifier | ...
在執行上AST一些轉變,我可能想簡單地隨身攜帶與在表達式中使用帶變量的一些額外的數據。到目前爲止,我所考慮過的所有這些選項似乎相當尷尬。我可以做一個新的數據類型:
data Exp' = Var' Identifier ExtraInfo | ...
但這意味着我需要一個新的定義Stmt'
,GDecl'
,以形成略有改變AST'
。另一種選擇是另一個數據構建器添加到原來Exp
,但只用它在程序中的一個特定部分:
data Exp = Var Identifier | Var' Identifier ExtraInfo | ...
如果你這樣做,typechecker再也不能阻止你在錯誤地使用Var'
該計劃的其他部分。 第三個選擇是簡單地保持周圍所有的時間額外的信息,即使它沒有相關的程序的其餘部分:
data Exp = Var Identifier ExtraInfo | ...
可行的,但它的醜陋,尤其是如果你只需要額外的信息簡要。現在,我剛把Map Indentifier ExtraInfo
中的額外信息加上AST
,明確地或通過狀態monad。例如,如果您需要使用不同的信息註釋同一個Identifier
的不同發生,這可能會變得很尷尬。
有沒有人有任何註釋嵌套數據類型的優雅技術?
也許嘗試'數據Exp a = Var標識符a | ...'?然後可以傳遞註釋但實際上不使用它們的函數在'a'中是多態的,那些不能處理註釋的函數將使用Exp()來註釋你具有類型爲Exp()的函數, - > Exp ExtraInfo',並且需要額外信息的轉換將使用'Exp ExtraInfo'。它基本上是「始終保持它」的選項,但類型檢查程序能夠強制執行使用它的階段。 – Ben 2014-10-06 01:09:46