nar*_*thi 40 oop scala module sml
ML模块系统是数据抽象的编程语言支持的高水准标记.但是,从表面上看,似乎可以很容易地在支持抽象类型成员的面向对象语言中进行编码.例如,我们可以在Scala中编码SML模块系统的元素,如下所示:
是否有任何重要的功能,如编码会错过?任何可以在SML模块中表达的编码都无法表达的东西?SML使得这种编码无法做出的任何保证?
And*_*erg 51
您无法轻易克服一些基本差异:
ML签名是结构类型,Scala特征是标称的:事实之后,任何适当的模块都可以匹配ML签名,对于Scala对象,您需要在定义时声明关系.同样,ML签名之间的子类型是完全结构化的.Scala 改进更接近结构类型,但有一些相当严格的限制(例如,它们不能引用它们自己的本地类型定义,也不包含对其范围之外的抽象类型的自由引用).
ML签名可以在结构上使用include和组成where.得到的签名等效于相应签名表达式或类型方程的内联扩展.Scala的mixin组合虽然在许多方面更强大,但也是名义上的,并且创造了一种不等价的类型.即使组合的顺序对于类型等价也很重要.
ML仿函数由结构参数化,因此通过类型和值,Scala的泛型类仅按类型进行参数化.要对仿函数进行编码,您需要将其转换为通用函数,该函数分别获取类型和值.一般来说,这种转换 - 在ML模块文献中称为相分裂 - 不能仅限于仿函数的定义和用法,因为在它们的调用点上它必须递归地应用于嵌套结构参数; 这最终要求所有结构始终进行相位分割,这不是您想要手动编程的样式.(也不可能将函数映射到Scala中的普通函数,因为函数不能表达参数和结果类型之间必要的类型依赖关系.编辑:从2.10开始,Scala支持依赖方法,它可以编码一些SML的一阶实例生成函子,虽然在一般情况下似乎不可能.)
ML具有改进和传播"半透明"类型信息的一般理论.Scala使用较弱的"路径依赖"类型的等式理论,其中路径表示对象.因此,Scala使用对象(具有类型成员)作为第一类值的能力来交换ML更具表现力的类型等价.如果不快速遇到可判定性或稳健性问题,您就不能轻易拥有两者.
编辑: ML可以自然地表达抽象类型构造函数(即更高类型的类型),这通常与仿函数一起出现.对于Scala,必须明确激活更高类型,这对于其类型系统更具挑战性,并且显然导致不可判断的类型检查.
当您超越SML,更高阶,一流或递归模块时,差异变得更加有趣.我们在MixML文章的 10.1节中简要讨论了一些问题.