6

次のコードの実行を理解しようとしています。

(def fibs 
  (concat (lazy-seq [0 1]) (lazy-seq (map + fibs (rest fibs)))))

これは、実行が次のようになると私が期待するものです

[0 1 : (map + [0 1] [1]) => 1
[0 1 1 : (map + [0 1 1] [1 1]) => 1 2
[0 1 1 1 2 : (map + [0 1 1 2] [1 1 2]) => 1 2 3
[0 1 1 1 2 1 2 3 : (map + [0 1 1 2 3] [1 1 2 3]) => 1 2 3 5
[0 1 1 1 2 1 2 3 1 2 3 5 .... 

結果が間違っているので、これは明らかに間違っています。私が思いついた唯一の実行で正しい結果が得られたのは次のとおりです。

[0 1 : (map + [0 1] [1]) => 1
[0 1 1 : (map + [1 1] [1]) => 2
[0 1 1 2 : (map + [1 2] [2]) => 3
[0 1 1 2 3 : (map + [2 3] [3]) => 5
[0 1 1 2 3 5 ....

これは、実行中の頭と尾の状態の正しい「表現」ですか? もしそうなら、なぜ(rest fibs)単一のアイテムを返すのですか? (rest (rest (rest [1 1 2 3]))) のような再帰呼び出しのためですか?

4

1 に答える 1

6

Fibs は(0 1 ...)((concat [0 1] ... )先頭にあるため) です。(rest fibs)です(1 ...)。それから(map + fibs (rest fibs))です

((+ 0 1) ...) => (1 ...)

だからフィブスは(0 1 1 ...). 次の項目を取得したので、さらに別の項目を計算できます。

(1 (+ 1 1) ...) => (1 2 ...)

そしてそれは続く...

(1 2 (+ 1 2) ...)

fibsが既に存在するかのように考え、 の状態が(map + fibs (rest fibs)既に存在する fibs のリスト上を移動していると考えてください (途中で必要なものすべてを計算することになるので問題ありません)。

2 つのシーケンスを書き留めておくことも役立ちます。

 (0 1 1 2 3 5 ...)
+(1 1 2 3 5 ...)
=(1 2 3 5 8 ...)

(ここで矢印を描いて、すでに得られたものと結果がどこに行くかを示しますが、ここではうまくできません)。

于 2012-11-16T21:53:17.400 に答える