OCaml中的相互递归类型

时间:2015-04-06 13:03:02

标签: haskell recursion ocaml algebraic-data-types mutual-recursion

在Haskell中,您可以执行以下操作:

Prelude> data Foo = Foo Bar; data Bar = Bar Foo

你怎么能在OCaml做同样的事情?我试过了:

                    ___
# type foo = Foo of bar;; type bar = Bar of foo;;
Error: Unbound type constructor bar

甚至可以在OCaml中定义相互递归的数据类型吗?如果不是那么为什么?

将数据定义与let表达式进行比较:相互递归的数据类型对应于使用let rec(或者更适合type rec以获得更好的短语)。能够定义相互递归数据类型的优点是什么?我的foobar例子是微不足道的。您能想到相互递归数据类型的任何非平凡用法吗?

2 个答案:

答案 0 :(得分:10)

使用and

type foo = Foo of bar
 and bar = Bar of foo

答案 1 :(得分:4)

ivg已回答了您的问题,但这是一个非平凡的相互递归类型。

module Stream = struct

  type 'a t    = unit -> 'a node
   and 'a node = Nil
               | Cons of 'a * 'a t 

end

这是真正的脊柱懒惰流。也就是说,你可以在没有相互递归类型的情况下构造它

type 'a t = Stream of (unit -> ('a * 'a t) option)

我的想法是,如果你愿意的话,你可以随时将一系列相互递归的类型减少为一个(尽管可能不是在OCaml中 - 我想到的编码会使非依赖类型的使用变得非常简单指数),但它肯定可以直接更明确。