OCaml,将惰性列表放入惰性树

OCaml,将惰性列表放入惰性树,ocaml,lazy-evaluation,Ocaml,Lazy Evaluation,我有两种类型: type 'a llist = LNil | LCons of 'a * (unit -> 'a llist);; type 'a lBT = LEmpty | LNode of 'a * (unit -> 'a lBT) * (unit -> 'a lBT);; 我需要编写一个函数来获取惰性列表并返回惰性BST。 我目前有两个函数,第一个(add,它获取元素和一个树,并返回一个包含此元素的树)看起来还可以,但

我有两种类型:

type 'a llist = 
      LNil 
    | LCons of 'a * (unit -> 'a llist);;

type 'a lBT = 
      LEmpty 
    | LNode of 'a * (unit -> 'a lBT) * (unit -> 'a lBT);;
我需要编写一个函数来获取惰性列表并返回惰性BST。 我目前有两个函数,第一个(add,它获取元素和一个树,并返回一个包含此元素的树)看起来还可以,但是第二个(它遍历列表并创建一个新的树来添加列表中的所有元素)我得到了错误。对我来说,这看起来不错,但我可能只是不明白什么。我不知道是什么

let rec add (elem, tree) = 
    match (elem, tree) with
      (None, _) -> LEmpty
        | (x, LEmpty) -> LNode (x, (function() -> add (None, LEmpty)), (function() -> add (None, LEmpty)))
        | (x, LNode (y, l, r)) when x < y -> LNode(y, (function () -> add (x, l())), r)
        | (x, LNode (y, l, r)) -> LNode(y, l, (function () -> add (x, r())));;

let toLBST listal = 
    let rec toLBST_rec listal tree =
        match listal with
          LNil -> tree
            | LCons(x, xs) -> toLBST_rec (xs()) add(x, tree)
    in toLBST_rec (listal, LEmpty);;

我不知道我该怎么做,它才能正常工作。我尝试了一些方法,但每次都会出错。

以下是您在代码中犯的各种错误:

  (None, _) -> LEmpty
这是错误的,
elem
没有理由成为选项类型。在
LEmpty
情况下,只需使用
LEmpty
定义返回的惰性树的子级

        | LCons(x, xs) -> toLBST_rec (xs()) add(x, tree)
您忘记了在
添加(x,tree)
周围加括号


您将
toLBST_rec
定义为接受两个参数,现在只传递一个错误类型的参数(列表和树的一对,而参数只需要一个列表)。您似乎对OCaml中多参数(currified)函数的语法感到困惑。您应该避免在函数声明和调用中使用
(…,…)
,而是定义
let rec add elem tree=
,等等。

可能会允许输出惰性树失去平衡,因此它的根不必是中间值-它可以只是列表的头。是的,顺序内和顺序后必须立即强制整棵树,但顺序前和宽度优先不一定会立即强制整棵树;在这种情况下,一个简单的快速排序就可以完成这项工作:将第一个元素作为轴心,然后将左、右子元素定义为列表其余部分的(惰性)分区的转换。再仔细考虑一下,上面绘制的快速排序应该相当于上面的
add
函数的惰性折叠,因此没有理由改变算法。美好的我删除了关于错误理解懒散选择的段落,谢谢。是的,
add
在输入懒散列表上的懒散折叠应该是
toLBST
;然后,对于惰性分区,我们必须小心地使用两个分支的预顺序遍历,或宽度优先遍历。当到达树的最左边节点(列表中最小的元素)时,输入列表将在该点完全消耗,但树尚未完全形成。对于预订单,我们在树构建方面更懒惰,而对于广度优先,我们在列表消费方面更懒惰。很好,分区两部分的非有序性带来了额外的自由。:)想一想,in-或post-order只会在需要结果列表的头时完全强制列表,但树也不会完全形成。在
add
,而不是
(None,)->LEmpty
中,它应该是
(Nil,)->tree
正如gasche所说,要么用pair定义,
let rec fun(a,b)=。。。在fun(x,y)
或有两个参数的情况下,
让rec fun a b=。。。在fun(x)(y)
,但是调用和定义应该一致。
        | LCons(x, xs) -> toLBST_rec (xs()) add(x, tree)
in toLBST_rec (listal, LEmpty);;