2008-08-30 37 views
11

我正在爲實驗語言編寫解釋器。該語言的三個主要結構是定義,陳述和表達式。定義可以包含語句和表達式,語句可以包含定義和表達式,一種表達式可以包含語句。我用聯合類型來表示所有這些,所以我可以很容易地在它們上使用模式匹配。理想情況下,我想將這些代碼放在不同的文件中,但OMake抱怨循環依賴問題。據我所知,跨模塊的循環類型定義是不允許的。處理OCaml中的循環依賴關係

我知道的唯一的辦法來解決,這是一次定義所有三種類型:

type defn = ... 
and stmt = ... 
and expr = ... 

看起來這需要所有的代碼類型是在同一個文件。有沒有辦法解決?你如何處理你的代碼中的循環定義?

回答

15

遞歸定義需要出現在同一個文件中。如果要將定義,語句和表達式分隔爲單獨的模塊,則可以使用recursive modules這樣做,但它們仍需要出現在同一個文件中。 DAG-ifying文件間依賴性是OCaml的煩惱之一。

12

這是很容易在它們指的類型參數化的類型解決:

type ('stmt, 'expr) defn = ... 
type ('defn, 'expr) stmt = ... 
type ('defn, 'stmt) expr = ... 

這種技術被稱爲「解開遞歸結」(參考難解的結),並在OCaml Journal文章描述。

乾杯, Jon Harrop。

3

另一個常用的解決方案是抽象接口中的類型。由於類型在接口中是抽象的,因此這些接口不是遞歸依賴的。在實現中,您可以指定類型,並且由於實現僅依賴於接口,所以它們也不是遞歸的。

唯一的問題是,使用這個解決方案,你不能在它們實現之外的這些類型上進行模式匹配。我個人喜歡將我的程序的所有類型定義在一個模塊中(我認爲它有助於程序的可讀性)。所以,OCaml的這個限制對我來說並不是一個問題。