[英]OCaml - converting trees with references to normal trees
我有两种树木:
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
Where This expression
指向Node (x, [])
内的空列表。 为什么类型不匹配?
这里的问题是你定义了两个构造函数Node
,第二个定义( type tree = Node of …
)遮蔽了第一个。
这意味着当你匹配t
并将其解构为Node(x, l)
,OCaml将其视为tree
,而不是ref_tree
(因此将l
视为tree list
而不是ref_tree list ref
)
解决此问题的一种方法是更改ref_tree
构造函数:
# 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>
(另一种方法是在模块Tree
和RefTree
定义那些类型并使用Tree.Node
和RefTree.Node
)
编译器在您的两个Node
构造函数( ref_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))
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.