【问题标题】:Making a function lazy in clojure在 clojure 中使函数变得惰性
【发布时间】:2015-10-08 18:49:41
【问题描述】:

我有这个功能,它似乎在有限的集合上工作得很好,但在无限的集合上却不行。有没有办法在其中构造一个 lazy-seq 以使其与无限 coll 一起运行,例如:(take 3 (m inc (range))) => (1 2 3)

(defn m [f c] (reduce #(conj % (f %2)) [] c))

【问题讨论】:

    标签: clojure lazy-sequences


    【解决方案1】:

    这似乎是map 的一个用例

    (map f c)
    

    或者(当它必须是一个向量时)

    (mapv f c)
    

    编辑: 地图的可能重新实现:

    (defn new-map [f coll]
      (if (seq coll)
        (lazy-seq
          (cons (f (first coll)) 
                (new-map f (rest coll))))))
    

    【讨论】:

    • 我正在尝试制作类似map
    • 所以你想重新实现地图?
    • 是否可以在其他表达式主体上使用lazy-seq,例如我的示例?类似:(defn m [f c] (lazy-seq (reduce #(conj % (f %2)) [] c)))
    • 你不能用reduce来偷懒。当您将 thing 的某些内容“放入”惰性序列中时,thing 将不会变得惰性!它将保持不变。使用lazy-seq 得到的懒惰如下:序列中的thing 只会在你到达/查看序列中的thing 时被评估。您的函数m 的结果与(mapv f c) 完全相同
    • 不,reduce 不是惰性的,它必须实现整个缩减集合。并且将其包装到惰性序列中根本没有帮助
    【解决方案2】:

    reduce 将继续从序列中获取元素,直到返回 nil。因此,reduce 永远不会返回无限序列。

    正如cmets中所指出的,reduced可以用来强制终止reduce,谢谢!

    【讨论】:

    • 好吧,你可以使用reduced 来终止无限序列。
    • 这意味着将reduce 放入if 表达式中?
    • 是的,您可以在这里查看示例:clojuredocs.org/clojure.core/…
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-06-17
    • 1970-01-01
    • 1970-01-01
    • 2010-12-08
    • 1970-01-01
    • 1970-01-01
    • 2011-02-06
    相关资源
    最近更新 更多