模組類型是模組層級的類型表達式等效物:它們指定模組的通用形狀和類型屬性。
|
|
另請參閱以下語言擴展:恢復模組的類型、在簽章內進行替換、類型級模組別名、屬性、擴展節點、生成式函子和模組類型替換。
表達式 modtype-path 等同於綁定到名稱 modtype-path 的模組類型。表達式 ( module-type ) 表示與 module-type 相同的類型。
簽章是結構的類型規格。簽章 sig … end 是值名稱、類型名稱、異常、模組名稱和模組類型名稱的類型規格集合。如果結構為簽章中指定的所有名稱提供定義(實作)(以及可能更多),並且這些定義符合簽章中給定的類型要求,則該結構將匹配簽章。
簽章中的每個規格之後允許使用一個可選的 ;;。它用作語法分隔符,沒有語義含義。
簽章中值元件的規格寫為 val value-name : typexpr,其中 value-name 是值的名稱,而 typexpr 是其預期的類型。
形式 external value-name : typexpr = external-declaration 類似,但它還要求該名稱實作為 external-declaration 中指定的外部函數(請參閱第 22 章)。
簽章中一個或多個類型元件的規格寫為 type typedef { and typedef },它由類型名稱的相互遞歸定義序列組成。
簽章中的每個類型定義都指定一個可選的類型方程式 = typexpr 和一個可選的類型表示 = constr-decl … 或 = { field-decl … }。匹配結構中類型名稱的實作必須與方程式中指定的類型表達式(如果給定)相容,並具有指定的表示形式(如果給定)。相反,該簽章的使用者將能夠依賴類型方程式或類型表示形式(如果給定)。更準確地說,我們有以下四種情況
簽章中的規格 exception constr-decl 要求匹配的結構提供具有定義中指定的名稱和參數的異常,並使該異常可供結構的所有使用者使用。
簽章中一個或多個類別的規格寫為 class class-spec { and class-spec },它由類別名稱的相互遞歸定義序列組成。
類別規格在第 11.9.4 節中進行了更精確的描述。
簽章中一個或多個類別類型的規格寫為 class type classtype-def { and classtype-def },它由類別類型名稱的相互遞歸定義序列組成。類別類型規格在第 11.9.5 節中進行了更精確的描述。
在簽章中,模組組件的規格寫成 module 模組名稱 : 模組類型,其中 模組名稱 是模組組件的名稱,而 模組類型 是其預期的類型。模組可以任意巢狀結構;特別是,函子可以作為結構的組件,而函子類型可以作為簽章的組件。
要指定一個作為函子的模組組件,可以寫成
而不是
簽章的模組類型組件可以指定為具體模組類型或抽象模組類型。
抽象模組類型規格 module type 模組類型名稱 允許名稱 模組類型名稱 由符合簽章的任何模組類型實作,但會對簽章的所有使用者隱藏模組類型的實作。
具體模組類型規格 module type 模組類型名稱 = 模組類型 要求名稱 模組類型名稱 由符合簽章的模組類型 模組類型 實作,但會使 模組類型名稱 和 模組類型 之間的相等性對簽章的所有使用者顯而易見。
簽章中的表達式 open 模組路徑 不會指定任何組件。它只會影響簽章後續項目的解析,允許以簡單名稱 名稱 而不是路徑存取 模組路徑 . 名稱 來引用由 模組路徑 表示的模組的組件。open 的作用域會在簽章表達式結束時停止。
簽章中的表達式 include 模組類型 會執行由 模組類型 表示的簽章組件的文字包含。它的行為就像包含簽章的組件被複製到 include 的位置。模組類型 引數必須參照到簽章的模組類型,而不是函子類型。
模組類型表達式 functor ( 模組名稱 : 模組類型1 ) -> 模組類型2 是函子(從模組到模組的函數)的類型,它接受類型為 模組類型1 的模組作為引數,並返回類型為 模組類型2 的模組作為結果。模組類型 模組類型2 可以使用名稱 模組名稱 來參照函子實際引數的類型組件。如果類型 模組類型2 不依賴於 模組名稱 的類型組件,則可以使用替代的簡短語法 模組類型1 -> 模組類型2 來簡化模組類型表達式。函子引數的類型沒有限制;特別是,函子可以接受另一個函子作為引數(「高階」函子)。
當結果模組類型本身是函子時,
可以使用縮寫形式
假設 模組類型 表示簽章,則表達式 模組類型 with 模組約束 { and 模組約束 } 表示相同的簽章,其中已將類型方程式添加到某些類型規格中,如 with 關鍵字後的約束所描述。約束 type [類型參數] 類型建構子 = 類型表達式 會將類型方程式 = 類型表達式 新增到受約束簽章的名稱為 類型建構子 的類型組件的規格。約束 module 模組路徑 = 擴充模組路徑 會將類型方程式新增到由 模組路徑 表示的子結構的所有類型組件,使它們等同於由 擴充模組路徑 表示的結構的相應類型組件。
例如,如果模組類型名稱 S 綁定到簽章
sig type t module M: (sig type u end) end
則 S with type t=int 表示簽章
sig type t=int module M: (sig type u end) end
而 S with module M = N 表示簽章
sig type t module M: (sig type u=N.u end) end
一個接受兩個類型為 S 的引數的函子,它們共享 t 組件,寫成
functor (A: S) (B: S with type t = A.t) ...
約束會從左到右添加。在每個約束應用之後,產生的簽章必須是應用約束之前的簽章的子類型。因此,with 運算子只能在簽章的類型組件上添加資訊,但永遠不能刪除資訊。