更好地表示递归多态类型结构

时间:2018-10-03 13:09:37

标签: 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;
  }

此实现的问题在于,我无法在以下代码段中表示值b

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

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

我需要能够代表一个node没有data却又有孩子的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 } }

所以我想出了以下实现:

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 } }

可以,但是首先有一个空字段,然后填充它似乎有点笨拙。我想知道是否存在一种与第二种等效的解决方案,但其解决方案与第一种类似,因为没有数据的节点不会由带有空数据字段的结构表示。

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

{{1}}

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

1 个答案:

答案 0 :(得分:2)

如果您希望保留'a tree类型的构造函数,则可以申请:

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})