在OO中编码标准ML模块

时间:2014-04-11 08:06:42

标签: scala oop module sml

The ML module system stands as a high-water mark of programming language support for data abstraction. 然而,从表面上看,似乎可以很容易地在支持抽象类型成员的面向对象语言中进行编码。例如,我们可以在Scala中编码SML模块系统的元素,如下所示:

  • SML签名:没有具体成员的Scala特征
  • 具有给定签名的SML结构:扩展给定特征的Scala对象
  • 由给定签名参数化的SML仿函数:Scala类将对象扩展为给定特征作为构造函数参数

是否存在任何重要功能,例如编码会错过?任何可以在SML模块中表达的编码都无法表达的东西? SML使得这种编码无法做出任何保证吗?

1 个答案:

答案 0 :(得分:49)

您无法轻易克服一些基本差异:

  • ML签名是结构类型,Scala特征是名义上的:事实之后,任何适当的模块都可以匹配ML签名,对于Scala对象,您需要在定义时声明关系。同样,ML签名之间的子类型是完全结构化的。 Scala 细化更接近结构类型,但有一些相当严重的限制(例如,它们不能引用它们自己的本地类型定义,也不包含对其范围之外的抽象类型的自由引用)。

    < / LI>
  • ML签名可以使用includewhere在结构上进行组合。得到的签名等效于相应签名表达式或类型方程的内联扩展。 Scala的mixin组合虽然在许多方面更强大,但也是名义上的,并且创造了一种不等价的类型。甚至组合的顺序对于类型等价也很重要。

  • ML仿函数由结构参数化,因此通过类型和值,Scala的泛型类仅按类型进行参数化。要对仿函数进行编码,您需要将其转换为通用的函数,它将类型和值分开。通常,这种转换 - 在ML模块文献中称为相分裂 - 不能仅限于仿函数的定义和用法,因为在它们的调用站点,它必须递归地应用于嵌套结构论点;这最终要求所有结构始终是相位分割的,这不是您想要手动编程的样式。 (也不可能将函数映射到Scala中的普通函数,因为函数无法表达参数和结果类型之间的必要类型依赖性。编辑:自2.10起,Scala支持依赖方法,可以编码SML的一阶生成函子的一些例子,虽然在一般情况下似乎不可能。)

  • ML有一个改进和传播“半透明”类型信息的一般理论。 Scala使用较弱的“路径依赖”类型的等式理论,其中路径表示对象。因此,Scala使用对象(具有类型成员)作为第一类值的能力来交换ML更具表现力的类型等价。如果不快速遇到可判定性或健全性问题,就不能轻易拥有两者。

  • 编辑: ML可以自然地表达抽象类型构造函数(即更高类型的类型),这通常与仿函数一起出现。对于Scala,必须明确激活更高种类,这对于其类型系统更具挑战性,并且显然会导致不可判断的类型检查。

当您超越SML,更高阶,一流或递归模块时,差异变得更加有趣。我们在MixML paper的第10.1节中简要讨论了一些问题。