Types 使用稍后在OCaml中的类型定义中声明的类型

Types 使用稍后在OCaml中的类型定义中声明的类型,types,ocaml,Types,Ocaml,我目前正在用OCaml构建一个程序,我有以下问题:我需要两种类型,其中包含另一种类型的值。基本上是这样的(但有点复杂): 我注意到我可以引用我以前没有定义的类型(所以这个声明不会引发任何错误),但是如果我尝试使用它,它会区分两种类型的b:定义中提到的a和我定义的b 我知道我可以用丑陋的方式来做: type 'b a = { x: some_other_type; next: 'b };; type b = NoA | SomeA of b a;; 但是我想知道是否有更好的

我目前正在用OCaml构建一个程序,我有以下问题:我需要两种类型,其中包含另一种类型的值。基本上是这样的(但有点复杂):

我注意到我可以引用我以前没有定义的类型(所以这个声明不会引发任何错误),但是如果我尝试使用它,它会区分两种类型的b:定义中提到的a和我定义的b

我知道我可以用丑陋的方式来做:

type 'b a = {
  x: some_other_type;
  next: 'b
};;

type b =
    NoA
  | SomeA of b a;;

但是我想知道是否有更好的解决方案(尽管我不得不承认我非常喜欢直接看到b是一种递归类型)。

您需要使用
一起定义这两种类型:

type a = {
  x: some_other_type;
  next: b
}

and b =
    NoA
  | SomeA of a;;

首先,您的假设是错误的,您可以引用未定义的类型,例如

# type a = {
  x: some_other_type;
  next: b
};;
      Characters 16-31:
    x: some_other_type;
       ^^^^^^^^^^^^^^^
Error: Unbound type constructor some_other_type
因此,定义了您的
some\u other\u类型。也许,您不久前在顶级会话中定义了它,但忘记了它。如果我定义了
some\u other\u type
,那么我将得到一个
未绑定类型构造函数b
错误。因此,
b
一些其他类型的
都是先前定义的。每次定义一个新类型(不是别名)时,它都会为您创建一个新的类型构造函数,因此
typea=a;;类型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;;


好的,我应该试试这个,因为它也适用于函数。谢谢它不应该是
next:b
而不是
next:“b
在第一种方法中?不,
b
尚未定义。因此,我们正在用
b
中的任何一个参数来参数化我们的类型
a
。我指的是第一种方法,中间有“and”。
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
}