将clojure`defn`重构为`fn`会导致ClassCastException

时间:2017-05-02 13:57:40

标签: clojure refactoring anonymous-function

我正在4clojure's Prime Numbers kata工作。我有完美的解决方案 (如果效率低下)在我的本地机器上,但它依赖于defn 在4clojure禁止。

(defn factors [n]
  (->> n
       range
       (map inc)
       (filter #(zero? (mod n %)))))

(defn prime? [n]
  (->> (factors n)
       (count)
       (= 2)))

(defn n-primes [n]
  (->> (range)
       (filter prime?)
       (take n)))

我试图重构它只使用匿名函数,但它会爆炸。

(fn x-primes [count]
  (let [x-factors (fn factors [n] (->> n range (map inc) (filter #(zero? (mod n %)))))
         x-prime? (fn [n] (->> (x-factors n) (count) (= 2)))]
        (->> (range)
             (filter x-prime?)
             (take count))))

抛出以下错误(在本地和4clojure的编辑器中运行时)

  

ClassCastException java.lang.Long无法强制转换为clojure.lang.IFn

在重构代码时我做错了什么?

另外,为什么你认为4clojure禁止defdefn

1 个答案:

答案 0 :(得分:6)

您正在使用参数名称隐藏count函数。 (count some-num)正在抛出错误,因为在此范围内,count是一个数字,而不是函数。

将参数名称从count更改为其他名称。

另外,在4Clojure的帮助页面中,有以下一行:

  

出于安全原因,禁止某些操作。例如,您将无法使用“def”或切换名称空间。

由于defn只是一个def包装宏,因此它也是禁止的。如何导致安全问题超出了我的范围。