scala - 在 OO 中编码标准 ML 模块

标签 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 是否能保证此编码无法实现?

最佳答案

有一些无法轻易克服的根本差异:

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

  • ML 签名可以使用 include 在结构上组成和where 。生成的签名相当于相应签名表达式或类型方程的内联扩展。 Scala 的 mixin 组合虽然在很多方面更强大,但也是名义上的,并且创建了一个不等价的类型。甚至组合顺序对于类型等效性也很重要。

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

  • 机器学习有一个提炼和传播“半透明”类型信息的通用理论。 Scala 使用“路径相关”类型的较弱方程理论,其中路径表示对象。因此,Scala 用 ML 更具表现力的类型等价性来换取使用对象(带有类型成员)作为一等值的能力。如果不快速遇到可判定性或健全性问题,您就无法轻松地同时拥有两者。

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

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

关于scala - 在 OO 中编码标准 ML 模块,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23006951/

相关文章:

arrays - 为什么 Scalaz 中没有 Array 的 Functor 实例

java - 为什么在 Java 中不重写静态方法?

java - 正确的 Java 继承结构

F#代码组织: types & modules

android - Scala Actor 线程控制

scala - 如何对 2 个以上的情况确定隐式优先级

java - 一个包中有两个 module-info.java

javascript - 运行从 ecmascript 6 模块加载的函数

scala - 基于 bool 值填充枚举集

java - 在 Java 中可观察