为什么不能使用行多态性将对象存储在异构容器中?



根据现实世界OCaml的第11章,行多态性不能用于创建异构容器。

特别是,行多态性不能用于在同一容器中放置不同类型的对象。例如,不能使用行多态性创建异构元素列表

给出的示例是:

type square = < area : float; width : int >;;
type shape = < variant : repr; area : float>
and circle = < variant : repr; area : float; radius : int >
and line = < variant : repr; area : float; length : int >
and repr =
 | Circle of circle
 | Line of line;;
# let hlist: < area: float; ..> list = [square 10; circle 30] ;;
    Characters 49-58:
    Error: This expression has type < area : float; radius : int >
           but an expression was expected of type < area : float; width : int >
           The second object type has no method radius

正如错误消息如此清楚地指出的那样,元素的类型不匹配。我的问题是为什么行多态性不能"隐藏"不匹配的记录的方法,即对容器中的所有类型进行交集?

如果你遵循逻辑结论的思路,那么你最终会得到一个类型错误较少的系统,但许多推断的类型<>没有方法。

这是可以做到的,但你必须像这样明确地这样做:

let hlist = [(square 10 :> shape); (circle 30 :> shape)]

它不是自动完成的原因可能是否则类型系统将变得不可判定(根据 http://caml.inria.fr/pub/docs/manual-ocaml/objectexamples.html 它已经处于不可判定性的边缘)。但我不知道细节。

最新更新