Recursion 递归polymorhphic类型结构的更好表示

Recursion 递归polymorhphic类型结构的更好表示,recursion,types,polymorphism,ocaml,Recursion,Types,Polymorphism,Ocaml,我正在实现一个树。在我的程序执行期间,数据被添加到节点 下面的代码显示了我的第一个实现: type 'a tree = | Node of 'a | Leaf type nodata_node = { b: nodata_node tree; } type data_node = { a: int; b: data_node tree; } type _ data = | Unknown : unit -> unit data

我正在实现一个树。在我的程序执行期间,数据被添加到节点

下面的代码显示了我的第一个实现:

type 'a tree =
  | Node of 'a
  | Leaf

type nodata_node =
  {
    b: nodata_node tree;
  }

type data_node =
  {
    a: int;
    b: data_node tree;
  }
type _ data =
  | Unknown : unit -> unit data
  | SomeInt : int -> int data

type 'a tree =
  | Node of ('a, 'a) node
  | Leaf

and ('a, 'b) node =
  {
    a: 'a data;
    b: 'b tree;
  }

let a = { a = Unknown (); b = Node { a = Unknown (); b = Leaf } }

let b = { a = Unknown (); b = Node { a = SomeInt 1; b = Leaf } }
此实现的问题在于,我无法在以下代码段中表示值
b

let a = { b = Node { b = Leaf } }

let b = { b = Node { a = 1; b = Leaf } }
我需要能够表示一个
节点
,该节点没有
数据
,但其子节点都有数据

因此,我提出了以下实施方案:

type 'a tree =
  | Node of 'a
  | Leaf

type nodata_node =
  {
    b: nodata_node tree;
  }

type data_node =
  {
    a: int;
    b: data_node tree;
  }
type _ data =
  | Unknown : unit -> unit data
  | SomeInt : int -> int data

type 'a tree =
  | Node of ('a, 'a) node
  | Leaf

and ('a, 'b) node =
  {
    a: 'a data;
    b: 'b tree;
  }

let a = { a = Unknown (); b = Node { a = Unknown (); b = Leaf } }

let b = { a = Unknown (); b = Node { a = SomeInt 1; b = Leaf } }
这是可行的,但一开始字段是空的,后来又被填充,这似乎有点笨拙。我想知道是否有一种方法可以使表示形式与第二种表示形式等效,但其解决方案与第一种类似,即没有数据的节点不是由数据字段为空的结构表示的

编辑: 我现在意识到,我对GADT的使用并没有给我提出的问题带来太多,因此,下面是我第二次尝试的简单版本:

type 'a tree =
  | Node of ('a, 'a) node
  | Leaf

and ('a, 'b) node =
  {
    a: 'a;
    b: 'b tree;
  }

let a = { a = (); b = Node { a = (); b = Leaf } }

let b = { a = (); b = Node { a = 1; b = Leaf } }

EDIT2:我想有一种方法可以通过函子和相互递归的定义来实现。我对一种不依赖于函子的解决方案感兴趣。

如果您希望将
保留为树型构造函数,您可以选择:

type 'a tree =
  | Node of 'a
  | Leaf
type child_node = {data:int; x: child; y:child}
and child = child_node tree
type parent = child tree

let x: parent = Node (Node {data=0; x=Leaf; y = Leaf})

如果您希望将
'保留为树
类型构造函数,您可以选择:

type 'a tree =
  | Node of 'a
  | Leaf
type child_node = {data:int; x: child; y:child}
and child = child_node tree
type parent = child tree

let x: parent = Node (Node {data=0; x=Leaf; y = Leaf})