多态变体和构造函数
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】:您可以同时拥有vlist
和btree
定义。从多态变体构建的值根据它们的结构进行类型化,因此相同构造函数的不同用途之间没有冲突。
这是一个展示了我尝试过的一些可能性的会话:
# 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 typing 和 subtyping。它类似于 OCaml 中的对象类型(实际上对象和多态变体是双重概念)。以上是关于多态变体和构造函数的主要内容,如果未能解决你的问题,请参考以下文章