4

このレイジー seq がスタック オーバーフローを引き起こす理由と、dorun にシーケンスを渡したときに発生しない理由を理解できません。

(defn very-lazy [s]
    (lazy-seq
   (if (seq s)
     [(first s) (very-lazy (rest s))]
     [])))

(dorun (very-lazy (range 200000000)))
>nil

(take 2 (very-lazy (range 20000000))
>...(1577 (java.lang.StackOverflowError

怠け者の場合take 2、怠惰な seq を 2 回だけ反復させる必要があります。

4

1 に答える 1

3

あなたの例では、関数は lazyseq を返します(0 (1 (2 (3 (...)))))。そのため、dorunstackoverflow なしで実行され (2 つの要素のシーケンスがあり0、評価さ(1 (2 (...)))dorunません)、second失敗します (repl が評価して出力しようとする無限のネストされたシーケンスを返します)。

私はあなたがこの解決策を探していると思います

(defn very-lazy [s]
  (lazy-seq
   (if (seq s)
     (cons (first s) (very-lazy (rest s)))
     [])))

(take 10 (very-lazy (range 200000000)))
-> (0 1 2 3 4 5 6 7 8 9)
于 2012-12-22T12:54:28.357 に答える