我目前正在OCaml中构建一个程序,我遇到了以下问题:我需要两种类型包含另一种类型的值。它基本上是这样的(但有点复杂):
type a = {
x: some_other_type;
next: b
};;
type b =
NoA
| SomeA of a;;
我注意到我可以引用之前没有定义的类型(所以这个声明不会抛出任何错误),但如果我尝试使用它,它会区分两种类型的b:定义中提到的一个,以及我定义的那个。
我知道我可以用丑陋的方式做到这一点:
type 'b a = {
x: some_other_type;
next: 'b
};;
type b =
NoA
| SomeA of b a;;
但我想知道是否有更好的解决方案(虽然我不得不承认我很想直接看到b是递归类型)。
答案 0 :(得分:5)
首先,你的假设是错误的,你可以引用未定义的类型,例如,
# type a = {
x: some_other_type;
next: b
};;
Characters 16-31:
x: some_other_type;
^^^^^^^^^^^^^^^
Error: Unbound type constructor some_other_type
因此,您的some_other_type
已定义。可能是你在前一段时间在你的顶级会议中定义它而忘了它。如果我定义some_other_type
,那么我会收到Unbound type constructor b
错误。因此,b
和some_other_type
都是先前定义的。每次定义新类型(不是别名)时,它都会为您创建一个全新的类型构造函数,因此type a = A;; type a = A
定义了两种不同(不兼容)的类型。实际上,您只能在交互式顶级中定义两个具有相同名称的类型(否则,如果您决定更改类型定义,则需要重新启动顶级)。 OCaml编译器不允许您在同一结构中定义两个具有相同名称的类型。
要解决您的问题,您可以使用递归类型
type some_other_type
type a = {
x: some_other_type;
next: b
}
and b =
NoA
| SomeA of a;;
或者,或者,通过使其中一种类型为多态,例如
来打破依赖性type some_other_type
type 'b a = {
x: some_other_type;
next: 'b
}
type b =
NoA
| SomeA of b a;;
或者
type some_other_type
type 'a b =
NoA
| SomeA of 'a
type a = {
x: some_other_type;
next: a b
}
答案 1 :(得分:3)
您需要使用and
一起定义两种类型:
type a = {
x: some_other_type;
next: b
}
and b =
NoA
| SomeA of a;;