2011-10-27 30 views
5

中定義它爲什麼這個工作正常?在模塊外部使用開放式聯合,它們在

module Account = struct 

type account_type = Current of float | Savings of float 

end 

let sarah = Account.Current 100.0;; 

儘管下面的最後一行產生了Error: syntax error

module Account = struct 

    type 'a account_type = [> `Current of float | `Savings of float ] as 'a 

end 

let pete = Account.`Current 100.0;; 

也就是說,爲什麼我不能在不打開模塊的情況下使用模塊外部的開放聯合類型?我應該說我已經發現,改變了最終行:

open Account;; 
let pete = `Current 100.0;; 

工作正常,但很明顯,如果我用account_type了很多,這是麻煩的,或者我在的任何代碼開始打開Account使用account_type的部分,這意味着我會犧牲我通過使用簽名獲得的抽象Account
我已經瀏覽了幾個OCaml教程以及INRIA文檔,並且我找不到任何提及你如何做到這一點。
每當我想要使用account_type時,是否可以避免打開模塊?

由於提前,

扎克

回答

6

在第二個例子中,你其實不必open Account可言,語法只是`Current 100.0。多形態變體標籤不參與任何特定類型。 `Current的類型是[> `Current ],這個(>)意味着類型至少爲`Current,並且由於這是該函數接受的類型的一個子集,所以它會很好地編譯。您可以將相同的值傳遞給接受同名多態變體的許多函數。當然,缺少靜態類型信息,打字錯誤和情況可能變得相當複雜。

Code Reuse through polymorphic variants談論了它們的一些優點和用例。

5

`Current這樣的多態變體常量是全局定義的,類似於整型常量。您不會說Account.10引用Account模塊中的整數10。

這是多態變體的優點(和缺點),您可以在不定義它們的情況下使用它們(比如在使用它之前不必定義10)。

因此,正如nlucaroni所說,您不必打開Account模塊即可訪問`Current

與整數不同,多態變體也可以帶參數(如在您的`Current 100.0中)。但參數的數量及其類型並不固定,並且它們甚至可以在代碼中不同位置的相同構造函數中變化。因此,通過nlucaroni也提到了複雜性。

[格式說明:要使單引號`顯示在打字機樣式的文本中,降格慣例是使用加倍的反引號來包圍文本。這在文本內部留下了單獨的反引號。或者至少它是爲我工作的。]

+0

啊,我試着用倒退來逃避反作用,所以每個參與者都會造成大量的混亂。 – nlucaroni

相關問題