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