在OO中编码标准ML模块

ML模块系统是数据抽象的编程语言支持的高水准标志。 然而,从表面上看,它似乎很容易用支持抽象types成员的面向对象语言进行编码。 例如,我们可以在Scala中对SML模块系统的元素进行编码,如下所示:

  • SML签名:没有具体成员的斯卡拉特质
  • 具有给定特征的SML结构:扩展给定特征的Scala对象
  • 通过给定签名参数化的SML函子:Scala类将扩展给定特征的对象作为构造函数参数

有什么重要的function,这样的编码会错过? 任何可以用SML模块表示的编码无法expression的东西? SML使这种编码无法做到的任何保证?

有几个基本的差异,你不能轻易克服:

  • ML签名是结构types,Scala特性是名义上的:一个ML签名可以在事实之后被任何适当的模块匹配,对于你需要在定义时间声明关系的Scala对象。 同样,ML签名之间的分类也是完全结构化的。 斯卡拉优化更接近结构types,但有一些相当严重的限制(例如,他们不能引用自己的本地types定义,也不包含自由引用抽象types超出其范围)。

  • ML签名可以在结构上使用includewhere来组成。 得到的签名等价于相应签名expression式或types等式的内联扩展。 Scala的mixin组合虽然在很多方面更强大,但是又是名义上的,并且创build了一个不等价的types。 即使是作文的顺序也是重要的。

  • ML仿函数是由结构参数化的,因此,通过这两种types和值,Scala的generics类只被types参数化。 要编码一个仿函数 ,你需要把它变成一个通用的函数 ,它需要分别的types和值。 一般来说,ML模块文献中称为相分离的转换不能仅限于函数的定义和使用,因为它们的调用点必须recursion地应用于嵌套结构参数; 这最终要求所有的结构都是一致的相分离的,这不是你想要手动编程的风格。 (也不可能在Scala中映射函子到普通函数,因为函数不能表示函数在参数和结果types之间的必要types依赖关系编辑:从2.10开始,Scala支持依赖方法,它可以编码一些SML的一阶例子生成函子,尽pipe在一般情况下似乎是不可能的。)

  • ML具有提炼和传播“半透明”型信息的一般理论。 斯卡拉使用“path依赖”types的弱等式理论,其中path表示对象。 因此,Scala交换了ML更具performance力的types等价体,以便能够使用对象(具有types成员)作为第一类值。 如果没有快速陷入可判定性或健全性问题,你不能轻易拥有这两者。

  • 编辑: ML可以自然地expression抽象types的构造函数 (即更高types的types),这常常出现在函子中。 对于Scala,更高的types必须被明确地激活,这对于它的types系统来说更具挑战性,并且显然导致不可判断的types检查。

当你超越SML,移到更高阶,一stream或recursion模块时,这些差异会变得更加有趣。 我们在我们的MixML论文 10.1节中简要讨论几个问题。

Interesting Posts