使用稍后在OCaml

时间:2016-10-21 18:17:17

标签: types ocaml

我目前正在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是递归类型)。

2 个答案:

答案 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错误。因此,bsome_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;;