[英]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.