阅读“类型和编程语言”,我对使用闭包和记录子类型的对象实现印象深刻(第18章)。是否有任何特殊原因OCaml不支持记录子类型(我知道对象确实如此)?事实上,我找不到任何支持此语言的语言。
答案 0 :(得分:22)
从技术上讲,OCaml的对象并不真正支持通常意义上的子类型,而是行多态。行多态性优于子类型有许多优点,特别是它更具表现力,并且在类型推断方面效果更好(子类型和类型推断根本不能很好地混合)。
对所有记录使用结构子类型或行多态性的主要问题是它需要更多涉及的运行时实现,因此也更昂贵。在简单记录可以简单地转换为普通元组的情况下,字段访问只是索引,结构子类型或行多态性需要透明地“切片”对象的能力,即在超类型下查看它并删除随机字段。通常,这需要通过散列进行字段查找(例如Ocaml的对象)或证据传递技术,其中函数或其任何被调用者使用的每个字段的索引必须作为除了实际记录之外的隐藏参数(例如,这就是SML#正在做的事情)。
在任何情况下,Ocaml 都有多态记录,它们只是被称为对象。但是如果你不需要它,你可以忽略它们周围的所有类乱。
答案 1 :(得分:9)
在打字的观点上,记录子类型非常危险。
假设您有三个字段的记录:a,b和c。而且你想创建一个只有两个字段的记录:a和c。在完成整个记录的阅读之前,编译器不知道你正在使用什么类型,如果你犯了错误,最后仍然无法帮助你:你忘了b字段。
我完全同意这种观点具有争议性,但我认为写ocaml的人是这样认为的。