6

我刚刚阅读了有关行多态性以及它如何用于可扩展记录和多态变体的内容。

然而,Ocaml 对多态变体使用子类型。为什么?它比行多态更强大吗?

4

2 回答 2

13

OCaml对多态变体(和对象,就此而言)同时使用行多态和子类型。< m1 : t1; m2 : t2; .. >“开放”对象类型(..字面上是类型的一部分)或“开放”变体类型涉及行多态性[> `K1 of t1 | `K2 of t2 ]。子类型用于能够在封闭的非多态类型<m1:t1; m2:t2> :> <m1:t1>[ `K1 of t1 ] :> [ `K1 of t1 | `K2 of t2 ].

行多态性允许避免需要有界量化来表示类型,例如“获取至少具有方法m的对象,并返回相同类型的对象”:子类型因此相当简单、明确,并且不能被抽象。相反,行多态性更容易推断,并且可以更好地与类型系统的其余部分配合使用。很少需要使用封闭类型和显式子类型,但这有时很方便——特别是,保持类型封闭会产生更容易理解的错误消息。

于 2013-05-27T15:02:30.923 回答
8

为了补充 Gabriel 的回答,思考这个问题的一种方法是,子类型化提供了普遍存在多态性的弱形式。当参数多态的两个方向都可用时,子类型的表现力大多被包含(尤其是当没有深度子类型时)。但在 Ocaml 中并非如此。

Ocaml 用实际的通用多态性代替了通用方面,但不断进行子类型化,为您提供一种它原本没有的存在量化形式。这是形成例如异构集合所必需的,例如<a: int> list您希望能够存储至少具有a正确类型的方法的任意对象。

我会更进一步说,虽然这通常被解释为 Ocaml 世界中的子类型,但您实际上可以将封闭行解释为存在于(未知)尾部上的量化。然后,强制通过:>将是存在的引入,从而更加忠实于行所建立的参数多态性世界。(当然,在这种解释下,#会进行隐含的存在消除。)如果我要从头开始设计一个类似 Ocaml 的系统,我可能会尝试以这种方式对其进行建模。

于 2013-05-27T15:33:29.703 回答