如何解决以懒惰清单为第一要素的问题?

时间:2018-12-03 08:37:35

标签: function functional-programming ocaml

我想使函数采用int的惰性列表并返回元素数量增加的惰性列表,每个元素x必须重复x次。例如,我将像常规的那样编写惰性列表,为了更易读,我将其赋予函数[1; 2; 3],则传回[1; 2; 2; 3; 3; 3]。

我写了一些必须做的代码:

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

let lhd = function
    | LNil -> failwith "lhd"
    | LCons (x, _) -> x
    ;;

let ltl = function
    | LNil -> failwith "ltl"
    | LCons (_, xf) -> xf()
    ;;

let increase llist = 
    let rec increaseHelper (count, lList) = match (count, lList) with
        | (0, LCons(_, xf)) -> increaseHelper((lhd (ltl llist)), (xf()))
        | (_, LCons(x, _)) -> LCons(x, function() -> increaseHelper(count - 1, lList))
        | (_, LNil) -> LNil
    in increaseHelper(lhd llist, llist)
    ;;

(* ltake函数在常规列表中返回n个惰性元素*)

let rec ltake = function
    | (0, _) -> []
    | (_, LNil) -> []
    | (n, LCons(x, xf)) -> x :: ltake(n - 1, xf())
    ;;

ltake (20,increase (LCons(4, function() -> LCons(3, function() -> LCons(1, function() -> LCons(4, function() -> LNil))))));;

此测试返回:-:int list = [4; 4; 4; 4; 3; 3; 3; 1; 1; 1; 4; 4; 4]

所以主要问题是,增量功能对于惰性列表的前两个元素可以正常工作,但是在3-无限元素处,它保存了2个元素中的语句,即重复了多少个元素

1 个答案:

答案 0 :(得分:3)

首先,您的代码无法编译。我想你是在哪里写的,

| (0, LCons(_, xf)) -> increaseHelper((lhd xf), (xf()))

你打算写

| (0, LCons(_, xf)) -> increaseHelper((lhd (xf())), xf())

但是这将失败,因为当lhd (xf())可能是xf()时,您调用LNil。实际上,如果列表为空,那么您一开始就会失败。

in increaseHelper(lhd llist, llist)

您可以尝试按照您的原始想法来修复代码,但使它变得复杂的部分原因是,当您达到0时,要重置计数器,您需要查看尾巴的头部(如果不是零)。

这是另一个想法。为什么增加而不是减少计数器?从计数器的0开始,然后增加直到计数器与头部匹配为止。看上去似乎没什么不同,但是因为重置计数器不需要您查看列表,所以它更容易。

let rec increaseHelper(n,llist) = match llist with        
    | LNil -> LNil
    | LCons(x,xf) -> if n == x
                     then increaseHelper(0, xf())
                     else LCons(x, function() -> increaseHelper(n+1, llist))

并从0开始拨打您的电话,

in increaseHelper(0, llist)