首页 文章

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

提问于
浏览
1

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

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

type b =
    NoA
  | SomeA of a;;

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

我知道我可以用丑陋的方式做到这一点:

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

type b =
    NoA
  | SomeA of b a;;

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

2 回答

  • 4

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

    # 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 已定义 . 可能是你在前一段时间在你的顶级 Session 中定义它而忘了它 . 如果我定义 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
    }
    
  • 3

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

    type a = {
      x: some_other_type;
      next: b
    }
    
    and b =
        NoA
      | SomeA of a;;
    

相关问题