模块表达式是值表达式的模块级等效项:它们计算结果为模块,从而为模块类型中表达的规范提供实现。
|
另请参见以下语言扩展:递归模块,一等模块,open 语句中的覆盖,属性,扩展节点 和 生成性函子。
表达式 module-path 计算结果为绑定到名称 module-path 的模块。
表达式 ( module-expr ) 计算结果与 module-expr 相同。
表达式 ( module-expr : module-type ) 检查 module-expr 的类型是否为 module-type 的子类型,也就是说,module-type 中指定的所有组件都在 module-expr 中实现,并且它们的实现满足 module-type 中给出的要求。换句话说,它检查实现 module-expr 是否满足类型规范 module-type。整个表达式计算结果与 module-expr 相同,只是 module-type 中未指定的所有组件都将被隐藏,并且无法再访问它们。
结构体 struct … end 是值名称、类型名称、异常、模块名称和模块类型名称定义的集合。定义按它们在结构体中出现的顺序计算。由定义执行的绑定的作用域扩展到结构体的末尾。因此,一个定义可以引用同一结构体中更早定义绑定到的名称。
为了与顶层短语(第 14 章)兼容,在结构体中每个定义之后和之前允许使用可选的 ;;。这些 ;; 没有语义意义。类似地,以 ;; 开头的 expr 允许作为结构体的组件。它等效于 let _ = expr,即 expr 为了其副作用而计算,但没有绑定到任何标识符。如果 expr 是结构体的第一个组件,则前面的 ;; 可以省略。
值定义 let [rec] let-binding { and let-binding } 以与 let … in … 表达式(参见第 11.7.2 节)相同的方式绑定值名称。绑定左侧出现的名称绑定到右侧对应的值。
值定义 external value-name : typexpr = external-declaration 将 value-name 实现为 external-declaration 中指定的外部函数(参见第 22 章)。
一个或多个类型组件的定义写成 type typedef { and typedef },它包含一系列类型名称的相互递归定义。
异常通过语法 exception constr-decl 或 exception constr-name = constr 定义。
一个或多个类的定义写成 class class-binding { and class-binding },它包含一系列类名称的相互递归定义。类定义在第 11.9.3 节中更详细地描述。
一个或多个类的定义写成 class type classtype-def { and classtype-def },它包含一系列类类型名称的相互递归定义。类类型定义在第 11.9.5 节中更详细地描述。
定义模块组件的基本形式是 module module-name = module-expr,它计算 module-expr 并将结果绑定到名称 module-name。
可以写
而不是
另一种派生形式是
等价于
模块类型的定义写成 模块 类型 模块类型名 = 模块类型。它将名称 模块类型名 绑定到表达式 模块类型 所表示的模块类型。
表达式 打开 模块路径 在结构体中不会定义任何组件,也不会执行任何绑定。它只是影响结构体中后续项目的解析,允许由 模块路径 表示的模块的组件以它们的简单名称 名称 代替路径访问 模块路径 . 名称 来引用。打开 的作用域在结构体表达式的末尾结束。
表达式 包含 模块表达式 在结构体中会将由 模块表达式 表示的结构体中的所有定义重新导出到当前结构体。例如,如果你定义了一个模块 S,如下所示
定义模块 B 为
等价于将其定义为
打开 和 包含 之间的区别在于,打开 只是为打开的结构体的组件提供简短的名称,而不会定义当前结构体的任何组件,而 包含 还会为包含的结构体的组件添加定义。
表达式 函子 ( 模块名 : 模块类型 ) -> 模块表达式 计算为一个函子,它接收类型为 模块类型1 的模块作为参数,将 模块名 绑定到这些模块,在扩展的环境中计算 模块表达式,并将生成的模块作为结果返回。对函子参数的类型没有限制;特别是,函子可以接收另一个函子作为参数(“高阶”函子)。
当结果模块表达式本身是一个函子时,
可以使用简写形式
表达式 模块表达式1 ( 模块表达式2 ) 计算 模块表达式1 为一个函子,并将 模块表达式2 计算为一个模块,并将前者应用于后者。 模块表达式2 的类型必须与函子 模块表达式1 所期望的参数类型匹配。