键入'树=空|节点' a *'树*'树;;
是类型定义,其中a
是类型参数,tree
是类型名称吗?
在Node of
中,Node
是内置类型的OCaml吗? of
是什么意思?
感谢。
答案 0 :(得分:4)
是'a
是类型参数,tree
是类型名称(这些通常在OCaml中称为变体)。这与大多数其他语言的顺序相反。 Node
是构造函数(在OCaml中称为标记),of
只是OCaml中的一个关键字,用于指定构造函数参数的类型。 Node
不是OCaml的内置类型(它甚至不是一种类型,而是我所说的构造函数)。
因此Node (5, Empty, Node (6, Empty, Empty))
类型为int tree
(类似于Java中的Tree<Int>
)。
如果你从一个更简单的变体开始,可能会更有意义。
type shape = Square of int | Rectangle of int * int
Shape
和Rectangle
是我刚刚编写的标记(再次构造函数),允许我构造shape
类型的值(在这种情况下,我选择{ {1}}只接受一个参数,因为只需要长度来指定一个正方形,而Shape
需要长度和宽度)。什么都没有Rectangle
或Shape
,但事情的类型可能是Rectangle
。
用英语读取该行的一种方法是“我已经定义了一个名为shape
的类型。shape
是单个整数的shape
或Square
两个整数。“
现在也许出于某种原因我也想标记我的形状。
Rectangle
引用type 'label labelledshape = LabelledSquare of 'label * int | LabelledRectangle of 'label * int * int
区分'
不是类型(例如label
),而是变量。这允许我编写类似int
LabelledSquare ("a label for a square", 5)
之类的内容
请注意,尽管这允许多态性,但这些不是OCaml中所谓的“多态变体”。我不会在这里讨论,我只是建议您查看OCaml文档或浏览Stack Overflow以获取更多详细信息。
答案 1 :(得分:1)
从该类型定义:
type 'a tree = Empty | Node of 'a * 'a tree * 'a tree;;
以下是OCaml编译器基于它所知道的“事实”:
tree
是一元类型构造函数。这意味着对于任何类型t
,t tree
也是一种类型(例如:int tree
)。Empty
是'a tree
的0-ary构造函数。这意味着Empty
的{{1}}类型t tree
。t
是一个3-ary构造函数。这意味着,如果Node
的类型为a
,则t
的类型为b
,t tree
为c has type
树, then
节点(a,b, c)has type
t tree (note: that's the same
t`)t tree
类型值的唯一两种方法。这意味着您可以使用模式匹配(match ... with | Empty -> ... | Node (a, b, c) -> ...
)。