我目前正在OCaml中构建程序,并且遇到以下问题:我需要两种类型,这些类型包含另一种类型的值。它基本上是这样的(但稍微复杂一点):
type a = {
x: some_other_type;
next: b
};;
type b =
NoA
| SomeA of a;;
Run Code Online (Sandbox Code Playgroud)
我注意到我可以引用以前未定义的类型(因此此声明不会引发任何错误),但是如果我尝试使用它,它将区分b的两种类型:在a的定义中提到的一种,以及我定义的一个
我知道我可以用丑陋的方式做到这一点:
type 'b a = {
x: some_other_type;
next: 'b
};;
type b =
NoA
| SomeA of b a;;
Run Code Online (Sandbox Code Playgroud)
但是我想知道是否有更好的解决方案(尽管我不得不承认我很喜欢直接能够看到b是递归类型)。
首先,您的假设是错误的,您可以引用未定义的类型,例如,
# type a = {
x: some_other_type;
next: b
};;
Characters 16-31:
x: some_other_type;
^^^^^^^^^^^^^^^
Error: Unbound type constructor some_other_type
Run Code Online (Sandbox Code Playgroud)
因此,您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;;
Run Code Online (Sandbox Code Playgroud)
或者,也可以通过使多种类型之一成为多态来打破依赖性,例如,
type some_other_type
type 'b a = {
x: some_other_type;
next: 'b
}
type b =
NoA
| SomeA of b a;;
Run Code Online (Sandbox Code Playgroud)
要么
type some_other_type
type 'a b =
NoA
| SomeA of 'a
type a = {
x: some_other_type;
next: a b
}
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
111 次 |
最近记录: |