Tree OCaml-将引用的树转换为普通树

Tree OCaml-将引用的树转换为普通树,tree,ocaml,Tree,Ocaml,我有两种树: type ref_tree = Node of int * ref_tree list ref type tree = Node of int * tree list 我想编写一个函数convert:ref_tree->tree,它可以将具有邻居的树保存为包含它们的列表的引用,并输出一个树,其中引用被更改为普通列表。以下是我尝试过的: let rec convert t = match t with | Node (x, l) ->

我有两种树:

type ref_tree = Node of int * ref_tree list ref
type tree = Node of int * tree list
我想编写一个函数
convert:ref_tree->tree
,它可以将具有邻居的树保存为包含它们的列表的引用,并输出一个树,其中引用被更改为普通列表。以下是我尝试过的:

let rec convert t =
        match t with
        | Node (x, l) ->
            if (!l = []) then Node (x, []) else
            Node (x, (List.map convert !l))
但OCaml在尝试编译时返回一个错误:

if (!l = []) then Node (x, []) else
Error: This expression has type 'a list
       but an expression was expected of type tree list ref

其中
此表达式
指向
节点(x,[])
内的空列表。为什么存在类型不匹配?

编译器在两个
节点
构造函数(一个
ref\u tree
和一个
tree
之间混淆了。您可以通过多种方式帮助解决此问题,包括:

let rec convert t =
  match (t : ref_tree) with
  | Node (x, l) ->
     if (!l = []) then Node (x, []) else
       Node (x, (List.map convert !l))

这里的问题是您定义了两个构造函数
节点
,第二个定义(
type tree=Node of…
)隐藏在第一个定义后面

这意味着当您匹配
t
并将其分解为
节点(x,l)
,OCaml将其视为
,而不是
ref_树
(因此将
l
视为
树列表

解决此问题的一种方法是更改
ref_树
构造函数:

# type ref_tree = Ref_node of int * ref_tree list ref;;
type ref_tree = Ref_node of int * ref_tree list ref

# let rec convert t =
          match t with
          | Ref_node (x, l) ->
              if (!l = []) then Node (x, []) else
              Node (x, (List.map convert !l));;
val convert : ref_tree -> tree = <fun>
#type ref_tree=int*ref_tree list ref;的ref_节点;;
类型ref_tree=int*ref_树列表ref的ref_节点
#让rec转换为t=
匹配
|参考节点(x,l)->
如果(!l=[]),则节点(x,[])else
节点(x,(List.map convert!l));;
val转换:参考树->树=
(另一种方法是在模块
Tree
RefTree
中定义这些类型,并使用
Tree.Node
RefTree.Node