我对此有所考虑。主要问题是,一般而言,我们不知道多态类型的值有多大。如果您没有此信息,则必须以某种方式获取它。单态化通过专门消除多态来为您获取此信息。装箱将一切放入已知大小的表示形式中,拳击为您提供此信息。
第三种选择是跟踪这些信息的种类。基本上,您可以为每种数据大小引入不同的种类,然后可以在特定大小的所有类型上定义多态函数。我将在下面概述这样的系统。
KindsType constructorsκA::=n::=|∀a:κ.A|α|A×B|A+B|A→BrefA|Pad(k)|μα:κ.A
在这里,高层次的想法是类型的类型告诉您将一个对象布置在内存中需要多少个单词。对于任何给定的大小,很容易在该特定大小的所有类型上实现多态。由于每种类型(甚至是多态类型)都具有已知的大小,因此编译并不比C难。
α:n∈ΓΓ⊢α:nΓ,α:n⊢A:mΓ⊢∀α:n.A:m
Γ⊢A:nΓ⊢B:mΓ⊢A×B:n+mΓ⊢A:nΓ⊢B:nΓ⊢A+B:n+1
Γ⊢A:mΓ⊢B:nΓ⊢A→B:1Γ⊢A:nΓ⊢refA:1
Γ⊢Pad(k):kΓ,α:n⊢A:nΓ⊢μα:n.A:n
A×BAB
引用很有趣-指针始终是一个单词,但是它们可以指向任何大小的值。这使程序员可以
通过装箱将多态实现到任意对象,但不需要
它们这样做。最后,一旦显示了明确的尺寸,引入填充类型通常很有用,该填充类型使用空间但不执行任何操作。(因此,如果要采用一个int和一对int的不相交的并集,则需要在第一个int处添加填充,以使对象布局统一。)
递归类型具有标准的形成规则,但是请注意,递归出现的大小必须相同,这意味着您通常必须将它们放在指针中才能进行分类。例如,列表数据类型可以表示为
μα:1.ref(Pad(2)+int×α)
因此,这指向一个空列表值,或一对int和一个指向另一个链接列表的指针。
对这样的系统进行类型检查也不是一件容易的事。我的ICFP论文中的算法与Joshua Dunfield的“ 用于较高等级多态性的完全和容易的双向类型检查”一起适用于这种情况,几乎没有任何变化。