15

阅读“类型和编程语言”,我对使用闭包和记录子类型的对象实现印象深刻(第 18 章)。OCaml 不支持记录子类型是否有任何特殊原因(我知道对象支持)?事实上,我找不到任何支持这一点的语言。

4

2 回答 2

23

从技术上讲,OCaml 的对象并不真正支持通常意义上的子类型,而是行多态性。与子类型相比,行多态性有许​​多优点,特别是它更具表现力,并且在类型推断方面效果更好(子类型和类型推断根本不能很好地混合)。

对所有记录使用结构子类型或行多态的主要问题是它需要更多涉及的运行时实现,因此也更昂贵。简单的记录可以很容易地转换为普通的元组,字段访问只是索引,结构子类型或行多态性需要透明地“切片”对象的能力,即在删除了随机字段的超类型下查看它。通常,这需要通过散列查找字段(例如 Ocaml 的对象)或证据传递技术,其中除了实际参数之外,函数或其任何被调用者使用的每个字段的索引都必须作为隐藏参数传递记录(例如,这就是 SML# 正在做的事情)。

在任何情况下,Ocaml都有多态记录,它们只是被称为对象。但是如果你不需要的话,你可以忽略他们周围的所有课堂混乱。

于 2013-03-06T07:11:38.643 回答
9

从打字的角度来看,记录子类型是非常危险的。

假设您有一个包含三个字段的记录:a、b 和 c。并且您想创建一个只有两个字段的记录:a 和 c。编译器在完成读取整个记录之前不知道您使用的是什么类型,并且如果您犯了错误,编译器仍然无法帮助您:例如,您忘记了 b 字段。

我完全同意这种观点是有争议的,但我认为这就是编写 ocaml 的人的想法。

于 2013-03-06T07:03:56.450 回答