「反復は無限の遅延シーケンスを提供します」
(= (range 20) (take 20 (iterate inc 0)))
私の質問は、なぜ 1 ではなく 0 から始まるのですか? ここで怠惰を理解する方法は?
「反復は無限の遅延シーケンスを提供します」
(= (range 20) (take 20 (iterate inc 0)))
私の質問は、なぜ 1 ではなく 0 から始まるのですか? ここで怠惰を理解する方法は?
デフォルトでは 0 から開始するため、公案では反復を 0 から開始するよう求めておりrange
、見栄えの良いステートメントになっています。プログラミングでは、1 ではなく 0 からカウントを開始するのが一般的で便利です。
(= (range 1 21) (take 20 (iterate inc 1)))
これが iterate の定義方法です
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)
まずはこんな感じ
(cons 0, (lazy-seq (iterate inc (inc 0))))
ここで、位置 1 (つまり、0 から数えてから 2 番目の位置) にある特別な lazy-seq 要素が最初にアクセスされると、事実上、その展開によって置き換えられます。
-- (iterate inc (inc 0))
-> (iterate inc 1)
-> (cons 1, (lazy-seq (iterate inc (inc 1))))
したがって、シーケンスは次のようになります
-- (cons 0, (lazy-seq (iterate inc (inc 0))))
-> (cons 0, (cons 1 (lazy-seq (iterate inc (inc 1)))))
2 番目の位置にある特別な lazy-seq 要素が最初にアクセスされると、実際には展開によって置き換えられます。
-- (iterate inc (inc 1))
-> (iterate inc 2)
-> (cons 2, (lazy-seq (iterate inc (inc 2))))
したがって、シーケンスは次のようになります
-- (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))
、それらの束を実現すると、それらはメモリに残ります。これが問題になる場合は、「頭を抱える」ことは避けてください。clojure.core/iterateは 2 つの引数を取ります:
fn
をシーケンスの最後の要素に適用します。適用すると、シーケンス内の次の要素が生成されます
シーケンスの初期値
(iterate inc 0)
0
シーケンスの最初の要素として持っています。
(take 1 (iterate inc 0)) ;; (0)