我想使函数采用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个元素中的语句,即重复了多少个元素
答案 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)