1

好像我做不到。

我想明白为什么我不能。

我肯定可以type 'a entry = Empty | Value of string * 'a * 'a entry;;,所以如果我想递归定义一个类型,我只能走union路线吗?

4

2 回答 2

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那么困难的原因。

于 2013-03-24T14:19:27.180 回答
1

当你这样做时type something = another type,你正在做一个类型同义词,就像typedefC 中的 a 一样。它创建了一个别名,你可以将其用作引用另一种类型的快捷方式。它本身并没有定义新的类型。因此,它不能是递归的。

当你这样做时type something = SomeContructor of ...,它定义了一个新的代数数据类型。这可以是递归的。

(Haskell 和 SML 对此更清楚;他们使用type类型同义词和data(Haskell)/ datatype(SML) 来定义新的代数数据类型。)

代数数据类型不一定需要有多个替代项。它在语法上是有效的

type 'a entry = Value of string * 'a * 'a entry

但是,在这种情况下,这可能没有用,因为,它怎么会结束呢?

于 2013-03-24T19:01:00.303 回答