【问题标题】:How to fix problem taking first element of lazy list?如何解决获取惰性列表的第一个元素的问题?
【发布时间】:2019-05-04 12:44:12
【问题描述】:

我想创建一个函数,该函数采用 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 个元素,重复元素多少次

【问题讨论】:

    标签: function functional-programming ocaml


    【解决方案1】:

    首先,您的代码无法编译。我想你写的地方,

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

    你的意思是写

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

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

    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)
    

    【讨论】:

    • 非常感谢您的帮助。我只有一个问题,是否可以让这个函数对零以下的数字起作用?
    • 我猜是这样,但是您需要说明它应该如何处理负数 x(将元素复制负数次是什么意思?)。如果您希望将负数 x 复制 0 次(即像 0 一样过滤掉),那么只需将 if n== x 更改为 if n>=x 即可。
    猜你喜欢
    • 2016-12-31
    • 2013-08-06
    • 2012-08-21
    • 2017-01-08
    • 2019-04-19
    • 1970-01-01
    • 1970-01-01
    • 2020-07-31
    • 1970-01-01
    相关资源
    最近更新 更多