我可以“输入”一个条目=字符串*'a *'一个条目;;`在OCaml中?

时间:2013-03-24 13:26:09

标签: functional-programming ocaml

似乎我不能。

我想知道为什么我不能。

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

2 个答案:

答案 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

然而,在这种情况下,这可能没用,因为它怎么会结束?