似乎我不能。
我想知道为什么我不能。
我确定可以type 'a entry = Empty | Value of string * 'a * 'a entry;;
,所以如果我想递归定义一个类型,我只能去union
路线?
答案 0 :(得分:6)
您的问题令人困惑,因为它只提到您不想要使用的类型!但是,我从你的标题中看到你想要使用直接递归类型。
如果您想直接递归类型,则需要在命令行上打开-rectypes
。但是,这并不是你真正想要做的事情。它允许太多类型真正不是你想要的。
$ ocaml
OCaml version 4.00.0
# type 'a entry = string * 'a * 'a entry;;
Error: The type abbreviation entry is cyclic
# ^D
$ ocaml -rectypes
OCaml version 4.00.0
# type 'a entry = string * 'a * 'a entry;;
type 'a entry = string * 'a * 'a entry
#
默认情况下未启用-rectypes
的原因是它允许将类型赋予实际编码错误的许多表达式。总的来说,额外的灵活性不值得放弃额外的错误检测。
这是我在旧的OCaml邮件列表消息中找到的一个例子:
$ ocaml -rectypes
OCaml version 4.00.0
# let f x = x :: x;;
val f : ('a list as 'a) -> 'a list = <fun>
#
启用-rectypes
后,这个相当荒谬的功能被接受了。但实际上它只适用于相当奇怪的列表类型。程序员很可能意图使用@
而不是::
将列表追加。不幸的是,直到-rectypes
开启时才会检测到此错误。
作为旁注,并且正如newacct指出的那样,你可能很快就会发现标题中的类型并不那么有用。它实际上只能代表循环或无限结构。这是在没有-rectypes
的情况下工作并不太困难的另一个原因。
答案 1 :(得分:1)
执行type something = another type
时,您正在执行类型同义词,就像C中的typedef
一样。它会创建一个别名,您可以将其用作引用的快捷方式另一种类型。它本身不定义新类型。因此,它不能递归。
执行type something = SomeContructor of ...
时,会定义新的代数数据类型。这可以是递归的。
(Haskell和SML对此更清楚;它们使用type
表示类型同义词,使用data
(Haskell)/ datatype
(SML)来定义新的代数数据类型。)< / p>
代数数据类型不一定需要有多个替代方案。 <#p>在语法上是有效的
type 'a entry = Value of string * 'a * 'a entry
然而,在这种情况下,这可能没用,因为它怎么会结束?