(在 OCaml 3.12 中引入;模式語法和封包類型推斷在 4.00 中引入;封包類型的結構比較在 4.02 中引入;從 4.05 開始需要較少的括號)
|
模組通常被認為是靜態元件。此擴展使得將模組打包為一級值成為可能,該值稍後可以動態解壓縮為模組。
表達式 ( module module-expr : package-type ) 將模組表達式 module-expr 表示的模組(結構或函式)轉換為封裝此模組的核心語言值。此核心語言值的類型為 ( module package-type )。package-type 註解可以省略,如果它可以從上下文中推斷出來。
相反地,模組表達式 ( val expr : package-type ) 將核心語言表達式 expr 求值為一個值,該值必須具有類型 module package-type,並提取封裝在此值中的模組。同樣,如果已知 expr 的類型,則可以省略 package-type。如果模組表達式已經被括號包圍,就像函式的參數一樣,則不需要額外的括號:Map.Make(val key)。
模式 ( module module-name : package-type ) 匹配類型為 package-type 的封包,並將其綁定到 module-name。它不允許在頂層 let 綁定中使用。同樣,如果它可以從封閉的模式中推斷出來,則可以省略 package-type。
出現在 ( module package-type ) 類型表達式和帶註解形式中的 package-type 語法類別表示模組類型的子集。此子集由具名模組類型和有限形式的可選約束組成:只能指定非參數化類型。
為了類型檢查的目的(並且從 OCaml 4.02 開始),封包類型使用模組類型的結構比較進行比較。
一般來說,模組表達式 ( val expr : package-type ) 不能在函式的本體中使用,因為這可能會與應用函式結合使用時導致不健全。自 OCaml 4.02 以來,這在兩個方面得到了放寬:如果 package-type 不包含名義類型宣告(即 使用正確的標識建立的類型),那麼這個表達式可以在任何地方使用,即使它包含此類類型,也可以在章節 12.15 中描述的生成函式的主體內使用。它也可以在局部模組綁定 let module module-name = ( val expr1 : package-type ) in expr2 的上下文中任何地方使用。
一級模組的典型用途是在執行時從簽名的多個實現中選擇。每個實現都是一個結構,我們可以將其封裝為一級模組,然後儲存在諸如雜湊表的資料結構中
然後,我們可以根據命令列引數選擇一個實現,例如
或者,可以在函式內執行選擇
使用一級模組,可以將某些程式碼參數化到模組的實現上,而無需使用函式。
要使用此函式,可以封裝 Set.Make 函式