行多态性和子类型化之间的主要区别是什么


20

我经常听到行多态比子类型化更好,但是我很难找到详细比较它们的方法。我对系统用户的观点特别感兴趣。

我确实看过这篇博客文章,但是它给我留下了比以前更多的问题。例如,它声称具有子类型的系统将分配一种类型,而具有行类型的系统将分配另一种类型。这是否意味着如果一个据称具有子类型的系统分配了“行类型”类型,那么它的命名是否正确?

我确实看到的一个主要区别是,行键入使对齐参数的类型成为可能(也就是说,编写一个仅与a参数字段有关的两个参数函数,但要求其参数具有相同的字段) 。

Answers:


10

子类型化表示给定一种类型的表达式,我们也可以给它另一种类型。我们说前者是后者的子类型,这种子类型关系引发了许多其他关系。在符号中,

ΓE:SS<:TΓE:T

这里的关键(以及我查看它的原因)是相同的表达式具有两种不同的类型。与参多态性语言隐式类型实例化,我们有以下子类型关系: 所有类型。如果类型实例化在System F中是显式的,则此子类型关系不成立。Ť(α.τ)<:τ[T/α]T

说一句,我们可以说一种行类型的语言(通常)具有产生其中。但是,实际上处理此问题的方式是通过更改类型相等(即统一)的概念,从而使,即它们统一。在这种情况下,子类型关系是平凡的 one。{1:A,2:B}<:{2:B,1:A}{1:A,2:B}{2:B,1:A}{ 12} = { 21} Ť < ŤSTS<:TT<:S{1:A,2:B}={2:B,1:A}T<:T

通常,当我们谈论一种具有子类型的语言时,是指一种与基础类型具有非平凡的子类型关系的语言,即没有自由变量的类型(当然,可以并且将为非基础类型生成子类型关系)。因此,具有行多态性的系统(例如Roy's)在这种意义上不是具有子类型的语言,尽管它确实具有来自任何隐式实例化参数化多态性语言的非平凡子类型关系。另一方面,结构子类型明确指出了地面类型的非平凡子类型关系。

对于行类型,我的意思是具有如上所述的非平凡的统一形式或等效形式。没有这个,行类型只不过是嵌套的元组。注意,行类型与参数多态性无关。我并不是要暗示行变量。从关于的参数()以上,结构子类型表示行类型,反之则不行。参数多态与行类型或结构子类型是正交的(在某种意义上,您可以拥有或不拥有它,肯定存在相互作用)。具有结构子类型+参数多态性的系统包含行类型+参数多态性(假设某种“记录并集”),因为后者中的每个术语都可以用前者中的相同类型来键入。前者也可以键入其他类型。使用Brian的例子,在结构性亚型和参数多态的系统answer将具有相同类型的行打字版本,但它也将有亚型版本的类型,以及

因此,您大概想比较行类型+参数多态性与不带参数多态性的结构子类型。前者的主要优点(有时甚至是缺点)是,它允许您全局传播信息。当被实例化为时,与它统一的所有事物也将被实例化。这可能会渗透到应用程序的根目录。通过大段代码携带行变量并不罕见。Subtyping的方法是忘记ρ{ c : Number }信息:从子类型到超类型会丢失(类型)信息。这通常可能就是您想要的:您关心的是一种通用类型,其他所有内容都不相关。我的偏见是要维护尽可能多的类型信息,而只明确地丢弃它。子类型化方法的缺点通常是由类型正确的程序证明的,但这仅是因为类型被推到了(无信息)“顶部”类型,例如空记录。重申一下,参数多态性(通常)保留类型信息,子类型化有意丢失它。


感谢您的详细回复!另一个问题:如果结构子类型化+参数多态性包含行类型+参数多态性,那么为什么还要使用后者?
Alex R

@AlexR正如Brian在他的博客文章中提到的那样,子类型在类型推断和许多其他方面(例如我提到的人体工程学问题)的交互作用极差。还有实现和语言复杂性问题。公平地说,“行类型”和子类型都有广阔的设计空间,因此“包含”是一个粗略的表述。
德里克·埃尔金斯
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.