Recursion 相互递归数据类型

Recursion 相互递归数据类型,recursion,ocaml,algebraic-data-types,Recursion,Ocaml,Algebraic Data Types,我试图创建一对相互递归的数据类型,以在OCaml中表示一棵红黑树,用于家庭作业。但是,我对OCaml语言非常不熟悉,所以我遇到了一些语法问题 以下是我到目前为止的想法: type 'a red_black_tree = | RedNode of 'a * ( 'a black_node * 'a black_node ) | BlackNode of 'a black_node and 'a black_node = | TwoRedNodes of 'a * ( 'a RedNode * 'a

我试图创建一对相互递归的数据类型,以在OCaml中表示一棵红黑树,用于家庭作业。但是,我对OCaml语言非常不熟悉,所以我遇到了一些语法问题

以下是我到目前为止的想法:

type 'a red_black_tree =
| RedNode of 'a * ( 'a black_node * 'a black_node )
| BlackNode of 'a black_node
and 'a black_node =
| TwoRedNodes of 'a * ( 'a RedNode * 'a RedNode )
| TwoBlackNodes of 'a * ( 'a black_node * 'a black_node )
| BlackLeaf;;
当我将其输入ocaml时,它会给出:

utop # type 'a red_black_tree =
| RedNode of 'a * ( 'a black_node * 'a black_node )
| BlackNode of 'a black_node
and 'a black_node =
| TwoRedNodes of 'a * ( 'a RedNode * 'a RedNode )
| TwoBlackNodes of 'a * ( 'a black_node * 'a black_node )
| BlackLeaf;;
Error: Syntax error
无法从子类型引用类型的子值吗?不是寻找问题的实际答案,只是语法澄清

更新

我在最初尝试之后就有了这个,但教授说它不是一对相互递归的数据类型:

更新2

问题3 红黑树是一种有时用来组织数字数据的树。它有两种类型的节点,黑色节点和红色节点。红色节点总是有一段数据和两个子节点,每个子节点都是黑色节点。黑色节点可以有:1)一段数据和两个子节点,它们是红色节点;2) 一段数据和两个子节点为黑色节点;或3)无数据且无子节点(即叶节点)。(这不是对红黑树的精确描述,但在本练习中取得了成功。)

编写一对相互递归的OCaml数据类型,表示红黑树中的红色节点和黑色节点。数据应该可以有任何类型,也就是说,您的类型在树中存储的数据类型中应该是多态的。

这是一个错误:

 | TwoRedNodes of 'a * ( 'a RedNode * 'a RedNode )
                            ^^^^^^^      ^^^^^^^
这里的
RedNode
应该是类型构造函数,而不是值构造函数。我猜想,您将再添加一个类型
'a red_node
,并定义
tworednode
分支,如下所示:

 | TwoRedNodes of 'a * ( 'a red_node * 'a red_node)
根据问题的上次更新,一个表达式将告诉您节点“n”的类型

(* to determine if a black node is a type 1 black node *)
match n with
| Black n' ->
    begin match n' with
    | Some n'' ->
        begin match n'' with
        | _, (Red _, Red _) -> "type 1 black node"
        | _, (Black _, Black _) -> "type 2 black node"
        | _ -> raise (Failure "invalid node")
        end
    | None -> "leaf node"
    end
| Red _ -> "red node";;
关于OCaml中类型的语义:OCaml中的类型名称必须始终以小写字母开头(例如
列表
数组
引用
),但类型构造函数必须以大写字母开头(例如
一些
)。类型是一个包含所有构造函数的伞

注:我认为这个问题甚至不需要相互递归的数据类型。以下方面应起作用:

type 'a node =
    Red of 'a * ('a node * 'a node)
  | Black of 'a option * ('a node option * 'a node option)

最终,红黑树的一对相互递归数据类型的实现是:

type ’a black_node = Leaf
| RNode of ’a * ’a red_node * ’a red_node
| BNode of ’a * ’a black_node * ’a black_node
and ’a red_node = RedNode of ’a * ’a black_node * ’a black_node;;

我用这样的例子更新了我的帖子。然而,当我向教授提出这个建议时,她说这不是一对递归类型的例子。她可能会挑剔这不是一对,而是三对您可以向她指出这样一个事实:
red\u node
依赖于
black\u node
black\u node
依赖于
red\u node
。这不是相互递归的吗?这是教授有时可能非常严格的一种可能性。我也会发布问题的描述。最糟糕的情况是,我会把我得到的交上来,因为作业只有5/200分。我同意你对相互递归数据类型的需要,但遗憾的是,教授说的很不幸……我仍然不清楚的主要部分是:1)一段数据和两个红色节点的子节点;2) 一段数据和两个子节点是黑色节点。('a node*'a node')如何限制该对是同构的?它不受节点类型的限制。使用此类型时,应始终将其匹配为同质。
type 'a node =
    Red of 'a * ('a node * 'a node)
  | Black of 'a option * ('a node option * 'a node option)
type ’a black_node = Leaf
| RNode of ’a * ’a red_node * ’a red_node
| BNode of ’a * ’a black_node * ’a black_node
and ’a red_node = RedNode of ’a * ’a black_node * ’a black_node;;