多态变体和构造函数

Polymorphic variants and constructors

我只是想知道 OCaml 的多态变体有多灵活。

我知道我可以在不同类型之间使用相同的构造函数,但相同的构造函数是什么意思?

我知道在这里使用 `Nil 没问题。

type 'a vlist = [`Nil | `Cons of 'a * 'a vlist]

type 'a btree = [`Nil | `Node of ('a * 'a btree * 'a btree)]

但是像这样使用 `Node 可以吗?

type 'a vlist = [`Nil | `Node of 'a * 'a vlist]

type 'a btree = [`Nil | `Node of ('a * 'a btree * 'a btree)]

您可以同时拥有 vlistbtree 定义。从多态变体构建的值根据它们的结构进行类型化,因此相同构造函数的不同用途之间没有冲突。

这是一个展示我尝试过的一些可能性的会话:

# type 'a vlist = [`Nil | `Node of 'a * 'a vlist];;
type 'a vlist = [ `Nil | `Node of 'a * 'a vlist ]
# type 'a btree = [`Nil | `Node of ('a * 'a btree * 'a btree)]  ;;
type 'a btree = [ `Nil | `Node of 'a * 'a btree * 'a btree ]
# let x : int vlist = `Node (3, `Nil);;
val x : int vlist = `Node (3, `Nil)
# let y : int btree = `Node (4, `Nil, `Nil);;
val y : int btree = `Node (4, `Nil, `Nil)
# let z = `Node (7, `Nil, `Nil, `Nil);;
val z : [> `Node of int * [> `Nil ] * [> `Nil ] * [> `Nil ] ] =
    `Node (7, `Nil, `Nil, `Nil)

z 示例的要点是表明无需提前声明类型。您可以使用多态变体构建几乎任何您喜欢的结构,并且类型将从结构中推断出来。同一构造函数的不同用途不必在数量或成分类型上一致。

(另一方面,我不是多态变体方面的专家;我很少使用它们,因为它们会导致大型表达式和复杂的错误消息。)