map
は怠け者である、とあなたはrecur
を経由して、マッピングの非常に深くネストされたマッピングを構築しています。バックトレースは少し不可解ですが、よく見ると、マップ、マップ、マップを見ることができる...それを修正するために
Caused by: java.lang.StackOverflowError
at clojure.lang.LazySeq.seq(LazySeq.java:56)
at clojure.lang.RT.seq(RT.java:450)
at clojure.core$seq.invoke(core.clj:122)
at clojure.core$map$fn__3699.invoke(core.clj:2099)
at clojure.lang.LazySeq.sval(LazySeq.java:42)
at clojure.lang.LazySeq.seq(LazySeq.java:56)
at clojure.lang.RT.seq(RT.java:450)
at clojure.core$seq.invoke(core.clj:122)
at clojure.core$map$fn__3699.invoke(core.clj:2099)
at clojure.lang.LazySeq.sval(LazySeq.java:42)
at clojure.lang.LazySeq.seq(LazySeq.java:56)
at clojure.lang.RT.seq(RT.java:450)
at clojure.core$seq.invoke(core.clj:122)
at clojure.core$map$fn__3699.invoke(core.clj:2099)
at clojure.lang.LazySeq.sval(LazySeq.java:42)
at clojure.lang.LazySeq.seq(LazySeq.java:56)
at clojure.lang.RT.seq(RT.java:450)
at clojure.core$seq.invoke(core.clj:122)
at clojure.core$map$fn__3699.invoke(core.clj:2099)
一つの方法は、怠惰を倒すためにその周りdoall
を置くことです。
(defn sum-bids [n offers std-dev]
(loop [n n sum (repeat offers 0)]
(if (zero? n)
sum
(recur (dec n) (doall (map + sum (reductions min (bid offers std-dev))))))))
user> (avg-bids 4000 10 5)
(100.07129114746716 97.15856005697917 95.81372899072466 94.89235550905231 94.22478826109985 93.72441188690516 93.32420819224373 92.97449591314158 92.67155818823753 92.37275046342015)
末尾再帰関数は、最後のものとして自身を呼び出します。私はあなたのコードのようなものは表示されません。 – Gabe
@Gabe:loop-recurは、テール再帰的な振る舞いを引き起こします。 http://clojure.org/special_formsを参照してください。 – Ralph
Ralph: 'loop-recur'は' for'ループパターンです。あなたの関数の中で最後のものとして 'recur'を呼び出すことは、彼がやっていることではないテール再帰です。 – Gabe