Clojure China

[4Clojure] #67 prime numbers

clojure
#1
(defn prime-numbers [n]
  (letfn
      [(prime? [n]
         (not-any? #(= 0 (mod n %)) (range 2 n)))]
    (reduce (fn [xs x]
              (cond (= n (count xs)) (reduced xs)
                (prime? x) (conj xs x)
                :else xs))
            []
            (drop 2 (range)))))

这是我的解法,结果4Clojure直接告诉我java.lang.RuntimeException: Unable to resolve symbol: reduced in this context, compiling:(NO_SOURCE_PATH:0)。不知各位有何见解。

#2
(:added (meta #'reduced))
"1.5"

4clojure 用的是 1.4

#3

谢谢提示。

正确做法:

(defn prime-numbers [n]
  (letfn
      [(prime? [n]
         (not-any? #(= 0 (mod n %)) (range 2 n)))]
    (take n
          (filter prime? (drop 2 (range))))))

错误做法:

(defn prime-numbers [n]
  (letfn
      [(prime? [n]
         (not-any? #(= 0 (mod n %)) (range 2 n)))]
    (take n
    (reduce (fn [xs x]
              (if
                (prime? x) (conj xs x)
                xs))
            []
            (drop 2 (range))))))

运行结果发现reduce其实不会返回lazy-seq,导致求值超时。而filter不论从语义角度,还是返回lazy-seq这一角度,都是合理、可行的。