My question is if there is any difference between Standard ML's module system and OCaml module system? Has OCaml all the support of functors , ascriptions etc... that SML has?
3 回答
在功能方面以及语义方面存在一些差异。
SML 支持但不支持 OCaml 的功能:
- 透明签名归属
- 模块级
let
- 对称共享约束
- 类型和值上的函子的语法糖
OCaml 4 有但没有 SML 的特点:
- 高阶函子
- 递归模块
- 本地模块
- 嵌套签名
- 模块作为一流的价值
- 通用模块共享 (
sig with module A = M
) module type of
然而,一些 SML 实现提供了其中一些作为扩展:例如,高阶函子(SML/NJ、Moscow ML、Alice ML)、本地和一流模块(Moscow ML、Alice ML)、模块共享(SML/NJ、 Alice ML)、嵌套签名(Moscow ML、Alice ML)和递归模块(Moscow ML)。
语义方面,最大的区别在于类型等价的处理,尤其是在函子方面:
在 SML 中,函子是生成的,这意味着将相同的函子两次应用于相同的参数总是会产生新的类型。
在 OCaml 中,仿函数是applicative,这意味着将相同的仿函数两次应用于完全相同的参数(加上额外的句法限制)会重现等效类型。这种语义更灵活,但也可能破坏抽象(参见我们在本文第 8 节中给出的示例)。
编辑:OCaml 4 添加了使函子生成的能力。
OCaml 有一个纯语法的签名概念,这意味着某些类型等价不能被类型系统表达,并且会被默默地丢弃。
编辑:考虑这个例子:
模块 F (X : sig type t end) = struct type u = Xt -> unit type v = Xt end 模块 M = F (结构类型 t = int end : sig type t end)
的类型
M
很简单,因此丢失了有关其类型和sig type u type v end
之间关系的任何信息,因为这通常不能用表面语法来表达。u
v
另一个显着的区别是 OCaml 的模块类型系统是不可确定的(即类型检查可能不会终止),因为它允许抽象签名,而 SML 不允许这样做。
至于语义,上面的 Andreas Rossberg 给出了一个更好、更详尽的答案。但是,关于此站点的语法,您可能正在寻找。
SML 中还有 abstype 工具,它类似于数据类型工具,只是它隐藏了数据类型的结构。OCaml 依赖于模块抽象来完成所有必要的隐藏。请注意,该站点未在 SML 中提及此设施。