我有一組Ocaml類型來表示一個語法樹。有類型的程序,類,方法,表達式等。例如,一種方法是通過一個記錄類型是這樣表示的:ocaml中的類型建模
type method = { return:typeid; args:typeid list; body:expr }
它包括一個返回類型,一種類型的每個參數,並且主體定義。我想鍵入檢查語法樹,併產生一種新的樹,看起來非常像舊的樹,除了每個表達式都有一個明確的typeid(僅在類型檢查後知道)與它相關聯。
一種選擇是聲明一組平行的類型:
type typed_expr = expr * typeid
type typed_method = { return:typeid; args:typeid list; body:typed_expr }
(* ... there are more types *)
的typed_method是必要的,因爲typed_expr是不同的類型。但我不想爲未檢查的AST和檢查的AST維護兩組幾乎相同的類型。
另一種方法是如下定義表達式:
type expr = {...; typ:typeid option}
這使我使用相同的類型定義爲輸入既檢驗器和輸出。區別在於我將大量檢查移動到檢查的語法樹的使用者代碼中。這裏有一個合同,typ
字段永遠不會在類型檢查器輸出中爲None
,並且在類型檢查器輸入中始終爲None
。
現在,每次我使用鍵入的樹時,訪問typ
字段內部值的唯一方法是首先檢查它是否爲None(它不應該是)。這使得所有後來的消費者代碼因爲額外的檢查而變得醜陋。
這些方法都不令我感到滿意。你會如何模型?
爲了避免重複,人們也可以考慮將表達式體留出類型化的AST,以便它只攜帶'typeid'。那麼類型化和非類型化的樹都需要始終遵守相同的樹結構,並且如果需要一起使用表達體和id,則必須同時迭代兩棵樹。 - 只是一個想法,可能是無稽之談 – user3240588