首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >clojure懒惰函数- Clojure

clojure懒惰函数- Clojure
EN

Stack Overflow用户
提问于 2014-02-14 03:00:52
回答 2查看 162关注 0票数 0

“迭代提供了无限的懒惰序列”

代码语言:javascript
复制
 (= (range 20) (take 20 (iterate inc 0)))

我的问题是为什么它从0开始,而不是从1开始?如何理解这里的懒惰?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2014-02-14 03:06:13

Clojure.core/迭代采用两个参数:

  1. 应用于序列中的最后一个元素的fn。应用时,它应该生成序列中的下一个元素。
  2. 序列的初始值。

(iterate inc 0)0作为序列的初始元素。

代码语言:javascript
复制
(take 1 (iterate inc 0)) ;; (0)
票数 2
EN

Stack Overflow用户

发布于 2014-02-14 05:01:16

koan要求迭代从零开始,因为默认情况下,range从0开始,这是一个漂亮的语句。在编程中,从0开始计数是典型且有用的,而不是1。但是,考恩可以写成从1开始(或任何其他数字)。

代码语言:javascript
复制
(= (range 1 21) (take 20 (iterate inc 1)))

下面是迭代的定义

代码语言:javascript
复制
user=> (source iterate)
(defn iterate
  "Returns a lazy sequence of x, (f x), (f (f x)) etc. f must be free of side-effects"
  {:added "1.0"
   :static true}
  [f x] (cons x (lazy-seq (iterate f (f x)))))

所以,下面是(iterate inc 0)最初的看法

代码语言:javascript
复制
(cons 0, (lazy-seq (iterate inc (inc 0))))

现在,当第一次访问位置1(即自0计数以来的第二个位置)的特殊延迟-seq元素时,它实际上被它的展开所取代。

代码语言:javascript
复制
 -- (iterate inc (inc 0)) 
 -> (iterate inc 1) 
 -> (cons 1, (lazy-seq (iterate inc (inc 1))))

所以,这个序列现在看起来

代码语言:javascript
复制
-- (cons 0, (lazy-seq (iterate inc (inc 0))))
-> (cons 0, (cons 1 (lazy-seq (iterate inc (inc 1)))))

当第一次访问位置2的特殊延迟-seq元素时,它实际上被它的展开所取代。

代码语言:javascript
复制
 -- (iterate inc (inc 1)) 
 -> (iterate inc 2) 
 -> (cons 2, (lazy-seq (iterate inc (inc 2))))

所以,这个序列现在看起来

代码语言:javascript
复制
 -- (cons 0, (cons 1 (lazy-seq (iterate inc (inc 1)))))
 -> (cons 0, (cons 1, (cons 2, (lazy-seq (iterate inc (inc 2))))))

一些需要注意的后果,但作为一个新用户通常不需要担心任何事情。

  • 身体中的任何副作用在访问之前都不会执行,然后只执行一次。
  • 因为您可以返回未完全实现的延迟序列,所以要注意动态范围的依赖,例如在with-块中返回。
  • 如果您持有对长/无限延迟序列的引用,例如(def numbers (iterate inc 0))并实现了其中的一堆,它们将保留在内存中。如果这是一个问题,避免“抱着头”。
票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/21770048

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档