刚开始学习100门问题的Clojure。我得到一个演员错误:
java.lang.ClassCastException: clojure.lang.LazySeq cannot be cast to clojure.lang.IFn
这是我的代码:
(defn doors [n]
(loop [n n
acc (repeat n false)]
(if (= n 0)
(open-doors acc)
(do
(let
[yy (map-every-nth not acc n)]
(recur (dec n) (acc yy)))))))
(defn map-every-nth [f coll n]
(map-indexed #(if (zero? (mod (inc %1) n)) (f %2) %2) coll))
(defn open-doors [d]
(for [doors d
n (iterate inc 0)
:when d]
n))
(doors 100)
答案 0 :(得分:3)
请记住,Clojure会尝试执行它遇到的每个列表:
(+ 1 2)
此处符号+
必须起作用,因此形式(+ 1 2)
成功执行。即使引用也没有取消规则:
'(+ 1 2) => (quote (+ 1 2))
引用表单执行并返回其内容作为结果。因此,Clojure中每个列表的第一个元素必须是可执行的:符号绑定到宏或函数,或特殊运算符。
在您的示例中,我们看到:
(acc yy)
acc
是一个懒惰的序列,(repeat n false)
的结果。它无法执行,因此您会收到错误。
注意,函数中有一个递归调用,因此recur
的参数是函数的参数。在Clojure函数的参数在使用之前得到评估。宏的参数没有。
答案 1 :(得分:0)
这是一个解决方案
(defn map-every-nth [f n coll]
(map-indexed
#(if (zero? (mod (inc %) n))
(f %2)
%2)
coll))
(defn doors []
(let [n 100]
(loop [p 1
state (repeat n false)]
(if (>= p 100)
state
(recur
(inc p)
(map-every-nth not p state))))))