Standard ML模块系统和OCaml模块系统有何不同(如果有)?

43

我的问题是标准ML的模块系统和OCaml模块系统之间是否有任何区别? OCaml是否具有SML拥有的所有functors、ascriptions等支持?

3个回答

57

在功能和语义上,SML和OCaml之间存在一些差异。

SML支持的功能但OCaml不支持:

  • 透明签名赋值
  • 模块级别的let
  • 对称共享约束
  • 针对类型和值的functor的语法糖

OCaml 4支持的功能但SML不支持:

  • 高阶functor
  • 递归模块
  • 本地模块
  • 嵌套签名
  • 作为一等公民的模块值
  • 一般模块共享(sig with module A = M)
  • module type of

然而,一些SML实现提供了这些扩展功能,例如:高阶functors(SML/NJ、Moscow ML、Alice ML)、本地和一等公民模块(Moscow ML、Alice ML)、模块共享(SML/NJ、Alice ML)、嵌套签名(Moscow ML、Alice ML)和递归模块(Moscow ML)。

就语义而言,最大的区别在于类型等价的处理方式,特别是与functor相关的处理方式:

在SML中,functor是生成的,这意味着将相同的functor应用于相同的参数两次总会产生新的类型。
在OCaml中,functor是应用的,这意味着将相同的functor两次应用于完全相同的参数(加上其他语法限制)会产生等效的类型。这种语义更加灵活,但也可能破坏抽象(例如,参见我们在this paper第8节中给出的示例)。
编辑:OCaml 4添加了可选地使functor生成的功能。
OCaml具有纯语法的签名概念,这意味着某些类型等价关系无法通过类型系统表达,并被默默地丢弃。
编辑:考虑以下示例:
module F (X : sig type t end) = struct type u = X.t -> unit type v = X.t end module M = F (struct type t = int end : sig type t end)
M的类型只是sig type u type v end,因此已经失去了其类型u和v之间关系的任何信息,因为通常无法在表面语法中表示它们。

另一个显著的区别是,OCaml的模块类型系统是不可判定的(即,类型检查可能不会终止),这是由于允许抽象签名,而SML不允许。


4
我认为你应该抓住机会谈一谈“未来”模块系统,或者更准确地说,在下一次干净的 ML 语言迭代中,这些特性集如何变化,假设“最近”(主要是你的)有关模块系统的研究得到合理的实施。这将使一个非常有趣的答案变得极其有趣。 - gasche
4
我认为在那个问题上跟风提问是不合适的 ;)。我的个人答案基本上就是我在上面链接的 F-ing 模块论文中所列出的——它以一种干净而(相当)简单的方式涵盖了所有列出的特性(包括生成和应用函子),但不包括递归模块。对于那些,我不太确定。OCaml 的递归模块对我来说过于临时和有限,但是全面的方法最终将导致放弃组成 ML 模块的主要部分之一,正如我们在 MixML 论文中描述的那样。目前还没有定论是否值得这样做。 - Andreas Rossberg
2
@fedvasu,是的,传统模块出现为特殊情况,但整个系统的性质发生了相当严重的变化。传统的ML模块在本质上非常功能性(例如将函数作为函数器,签名作为类型的自然概念)。MixML方法看起来越来越少功能性,更多地面向对象,包括其中涉及的一些问题(例如更复杂的类似对象的基元,模块作为值和类型的混合角色以及初始化中可观察到的副作用)。问题是,这是一个错误还是一个特性? ;) - Andreas Rossberg
2
@fedvasu,这取决于您所指的Odersky的具体陈述。;) 关于足够好的问题:要么根本不使用递归(许多人认为这是更可取的),要么咬紧牙关,走向类似于MixML的整个方向。我见过的所有临时递归模块概念都会引入更多问题和/或过于有限,无法承载其重量,我的看法是如此。 - Andreas Rossberg
1
@GregoryNisbet,请查看语言定义书的第18页(图18),链接:http://sml-family.org/sml97-defn.pdf。简单来说,形式_funid(dec)_和_funid(spec)_允许您在定义一个函数对象时写成`F(type t)F(type t; val x:t)`,并且对于函数的应用也是类似的。 - Andreas Rossberg
显示剩余8条评论

2

关于语义学方面,Andreas Rossberg在上面给出了更好、更详细的答案。然而,就语法而言,这个网站可能是您要寻找的内容。


0

SML 中还有 abstype 工具,它类似于 datatype 工具,但它隐藏了 datatype 的结构。OCaml 依靠模块抽象来进行必要的隐藏。请注意,this site 没有提到 SML 中的此工具。


是的,我故意省略了它,因为它被广泛认为是一项过时的功能。它早于基于模块的抽象化。 - Andreas Rossberg

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接