为什么';OCaml支持记录子类型?

为什么';OCaml支持记录子类型?,ocaml,record,subtyping,Ocaml,Record,Subtyping,阅读“类型和编程语言”,我对使用闭包和记录子类型的对象实现印象深刻(第18章)。OCaml不支持记录子类型有什么特别的原因吗(尽管我知道对象支持)?事实上,我找不到任何支持这一点的语言。从打字的角度来看,记录子类型是非常危险的 假设您有一个包含三个字段的记录:a、b和c。您想要创建一个只有两个字段的记录:a和c。编译器直到读取完整个记录才知道您使用的是什么类型,如果您犯了错误,编译器仍然无法帮助您:例如,您忘记了b字段 我完全同意这种观点是有争议的,但我认为编写ocaml的人就是这样想的。从技术

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

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

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


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

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

对所有记录使用结构子类型或行多态性的主要问题是,它需要更复杂的运行时实现,因此成本也更高。简单记录可以简单地转换为纯元组,字段访问只是索引,结构子类型或行多态性要求能够透明地“切片”对象,即在移除随机字段的超类型下查看它。通常,这需要通过散列(如Ocaml的对象)进行字段查找,或者使用证据传递技术,其中函数或其任何被调用方使用的每个字段的索引必须作为隐藏参数传递给实际记录(例如,SML#就是这样做的)


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

SML有记录子类型。OCaml的对象是带有子类型的记录。结构子类型是强大的,但它的类型错误通常是隐蔽的。所以OCaml用户通常更喜欢没有子类型的简单记录。感谢您指出SML!SML中的记录子类型和OCaml中的对象结构类型之间有什么区别吗?是的,类混乱是让我感到不快的地方。我是OCaml新手,但我期待了解更多关于其对象系统的信息。无论如何,谢谢你的回答!谢谢你指出这一点。我会投票,但我的声誉太低了;)嗯,我不太明白。子类型化意味着您可以在需要2字段记录的地方使用3字段记录。但在您的示例中,您创建了一个2字段记录(可能是错误的)。即使使用子类型,编译器也只允许您在实际需要2个字段(或更少)的地方使用它。但这很好,因为这些地方甚至不会看到你的第三个领域。