Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/clojure/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Clojure 这段代码中的惰性序列是如何运行的_Clojure_Lazy Sequences - Fatal编程技术网

Clojure 这段代码中的惰性序列是如何运行的

Clojure 这段代码中的惰性序列是如何运行的,clojure,lazy-sequences,Clojure,Lazy Sequences,代码如下: (def fib-seq (lazy-cat [0 1] (map + (rest fib-seq) fib-seq ))) 正如我所理解的,fib-seq是一个惰性序列生成器,它生成一系列斐波那契数。 通过查看(取5个fib-seq)我将得到如下fibonacci数: (01123) 但我无法理解在需要时如何生成惰性序列,因此我添加了一些副作用 (def fib-seq (lazy-cat [0 1] (map + (do (println "R") (rest fi

代码如下:

(def fib-seq (lazy-cat [0 1]  (map + (rest fib-seq) fib-seq )))
正如我所理解的,
fib-seq
是一个惰性序列生成器,它生成一系列斐波那契数。
通过查看
(取5个fib-seq)
我将得到如下fibonacci数:
(01123)

但我无法理解在需要时如何生成惰性序列,因此我添加了一些副作用

(def fib-seq (lazy-cat [0 1] (map + 
    (do (println "R") (rest fib-seq)) 
    (do (println "B") fib-seq))))
通过添加
println
,我希望只要惰性序列在需要时尝试生成新条目,它就会打印出
R
B
,但不幸的是结果是这样的

user=> (take 5 fib-seq) ; this is the first time I take 5 elements
(0 R
B
1 1 2 3)

上面的输出看起来很奇怪,因为它没有按元素打印R和B元素,但是让我们看看下一步。 首次拍摄元素后:

user=> (take 20 fib-seq)
(0 1 1 2 3 5 8 13 21 34 55 89 144 233 377 610 987 1597 2584 4181)
我再也不会收到
R
B
,这让我感到困惑,因为它与我对惰性序列生成的理解相冲突

有人能一步一步地给我解释一下吗?
顺便问一下,是否有可能使用
debug
实用程序一步一步地调试它,就像
Java
C
一样?

好的,一步一步:

  • 以下是懒猫的源代码:

    (defmac)
    “扩展到生成延迟串联序列的代码
    提供的coll的。每个coll expr在
    需要。
    (懒猫xs ys zs)==(concat(懒序列xs)(懒序列ys)(懒序列zs))”
    {:添加了“1.0”}
    [&colls]
    `(concat~@(map#(list`lazy seq%)colls)))
    
    因此,您的代码:

    (def fib seq(懒猫[01](映射+
    (do(打印字母“R”)(其余字母如下)
    (do(println“B”)fib-seq)
    
    扩展到:

    (def fib seq(concat(lazy seq[01]))
    (续)+
    (do(打印字母“R”)(其余字母如下)
    (do(println“B”)fib seq(()())))
    
    concat
    本身返回一个延迟序列,这意味着在遍历
    fib-seq
    之前,不会计算
    concat
    表单的主体

  • 当您第一次遍历
    fib-seq
    时(当您获取第一个
    5
    元素时),首先计算
    concat
    表单的主体:

    (concat(惰性序列[01])
    (续)+
    (do(打印字母“R”)(其余字母如下)
    (do(println“B”)fib-seq)
    
    concat
    返回的惰性序列的前两个元素取自
    (lazy seq[01])
    ,后者又取自
    [01]
    ;在这一点之后,
    [01]
    被耗尽,
    (lazy seq[01])
    也被耗尽,
    concat
    序列的下一个元素取自
    (lazy seq(map…)
    子序列

    这里对
    do
    特殊表单进行评估,这两种表单都是如此,您可以看到
    R
    B
    打印出来。
    do
    的语义是计算其中的所有表单,然后返回最后一个表单的结果

    所以
    (do(println“R”)(rest fib seq)
    打印
    R
    ,然后返回
    (rest fib seq)
    (do(println“B”)fib seq)的结果
    打印
    B
    ,然后返回
    fib seq

    (map…
    返回惰性序列;当遍历到达
    fib-seq
    的第三个元素时,计算
    映射
    序列的第一个元素;它是
    fib-seq
    (即
    0
    )的第一个元素与
    (其余fib-seq)
    的第一个元素(即
    fib-seq
    (即
    1
    )的第二个元素之和。在这一点上,这两个函数都已经被计算过了,所以我们不会以无限递归结束

    对于下一个元素,
    map
    的惰性阻止了无限递归的发生,神奇的事情发生了

  • 在您第二次遍历
    fib-seq
    (即
    (取20个fib-seq)
    )时,它的前几个元素已经过评估,因此不会重新评估
    do
    特殊形式,并且遍历继续进行,不会产生副作用


  • 要在从
    (rest fib-seq)
    fib-seq
    提取新元素时打印
    R
    B
    ,必须执行以下操作:

    (def fib序列
    (懒猫[01]
    (地图+
    (图#(do(println“R”)%)(其余为下文)
    (图#(do(println“B”)%)fib seq(())))
    
    好的,一步一步:

  • 以下是懒猫的源代码:

    (defmac)
    “扩展到生成延迟串联序列的代码
    提供的coll的。每个coll expr在
    需要。
    (懒猫xs ys zs)==(concat(懒序列xs)(懒序列ys)(懒序列zs))”
    {:添加了“1.0”}
    [&colls]
    `(concat~@(map#(list`lazy seq%)colls)))
    
    因此,您的代码:

    (def fib seq(懒猫[01](映射+
    (do(打印字母“R”)(其余字母如下)
    (do(println“B”)fib-seq)
    
    扩展到:

    (def fib seq(concat(lazy seq[01]))
    (续)+
    (do(打印字母“R”)(其余字母如下)
    (do(println“B”)fib seq(()())))
    
    concat
    本身返回一个延迟序列,这意味着在遍历
    fib-seq
    之前,不会计算
    concat
    表单的主体

  • 当您第一次遍历
    fib-seq
    时(当您获取第一个
    5
    元素时),首先计算
    concat
    表单的主体:

    (concat(惰性序列[01])
    (续)+
    (do(打印字母“R”)(其余字母如下)
    (do(println“B”)fib-seq)
    <
    
    (map + (rest [0 1 ..]) [0 1 ..] ); the '..' means it is a lazy sequence
    
    (map + [1 ..]  [0 1 ..] )
            ^       ^
            | ----- |
                |
                +
                1
    
    [0 1 1 ..]
    
    (map + (rest [0 1 1..]) [0 1 1..] )
    
    (map + [1 1..] [0 1 1..] )
    
    (map + [1 1..] [0 1 1..] )
              ^       ^
              | ----- |
                  |
                  +
                  2
    
    0 1 1 2 3 5 ..   
    1 1 2 3 5 ..