多态变体和构造函数

Posted

技术标签:

【中文标题】多态变体和构造函数【英文标题】:Polymorphic variants and constructors 【发布时间】:2022-01-16 15:32:28 【问题描述】:

我只是想知道 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)]

【问题讨论】:

【参考方案1】:

您可以同时拥有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 示例的重点是表明无需提前声明类型。您可以使用多态变体构建几乎任何您喜欢的结构,并且将从结构中推断出类型。同一个构造函数的不同用途不必在数量或组成部分的类型上一致。

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

【讨论】:

我想这自然会引出下一个问题……你如何对这些类型进行模式匹配?快速回到 OCaml 手册! 关键字:duck typingsubtyping。它类似于 OCaml 中的对象类型(实际上对象和多态变体是双重概念)。

以上是关于多态变体和构造函数的主要内容,如果未能解决你的问题,请参考以下文章

OCaml 错误:“变体类型没有构造函数 ::”

C#多态构造函数

面向对象的封装继承多态以及构造函数

在Python 3中,超类可以多态地调用子类的构造函数

Boost变体模糊构造[重复]

2017-4-16 多态 构造函数 方法重载 静态方法和静态成员