【问题标题】:OCaml - converting trees with references to normal treesOCaml - 将树与普通树的引用转换
【发布时间】:2015-03-16 13:38:43
【问题描述】:

我有两种树:

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

This expression 指向Node (x, []) 内的空列表。为什么会出现类型不匹配?

【问题讨论】:

    标签: tree ocaml


    【解决方案1】:

    这里的问题是你定义了两个构造函数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>
    

    (另一种方法是在模块TreeRefTree 中定义这些类型,并使用Tree.NodeRefTree.Node

    【讨论】:

      【解决方案2】:

      编译器会混淆您的两个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))
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2015-07-05
        • 1970-01-01
        • 2016-02-04
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多