【问题标题】:clojure - function not returning a lazy sequenceclojure - 函数不返回惰性序列
【发布时间】:2014-09-06 12:18:52
【问题描述】:

我很困惑为什么下面的代码在我调用lazy-seq 时会进入无限循环并且不返回惰性序列:

 (= (take 5 ((fn [func se] 
               (lazy-seq 
                (reduce (fn [acc item] 
                          (conj acc (func (last acc) item)))
                        [(first se)] (rest se)))) 
             + 
             (range)))
     [0 1 3 6 10])

repl 只是随着 range 被无限调用而旋转。

我怎样才能让这个函数表现得惰性?

【问题讨论】:

    标签: clojure


    【解决方案1】:

    为了构造一个惰性序列,您需要返回一个根据需要实现的序列。

    您在函数中所做的只是在 lazy-seq 调用中封装无限缩减。

    有一种模式通常有效,并且只在需要时实现新元素:

     (lazy-seq
         (cons element (recursion ..
    

    这意味着如果您想构建一个惰性 reduce,您将按照以下方式做一些事情:

     (fn [f s init]
        (lazy-seq
            (let [acc (f (first s) init)]
               (cons acc (recur f (rest s) acc))
    

    在这种情况下,您返回的序列将作为部分实现的序列存在于内存中

      (0 1 3 (recur + (rest s) 3))
    

    剩下的元素只存在logically作为所谓的递归。

    你可以看看this previous answer解释reduce的非懒惰。

    【讨论】:

    • recur 会不会产生与 reduce 相同的结果,它只会旋转?
    • 否,因为reduce需要迭代直到序列为空,因此您可以获得最终结果,建议的函数仅在需要时重复。你也可以使用reductions
    • 谢谢,我正在尝试重新创建缩减以增加我的 clojure 知识,所以这只是为了好玩
    • 好的,你认为你的问题已经回答了为什么你不能在惰性序列调用中包装 reduce?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2010-12-08
    • 1970-01-01
    • 2023-02-05
    • 1970-01-01
    • 2011-06-26
    • 2014-06-17
    • 1970-01-01
    相关资源
    最近更新 更多