在函数中使用带有列表的引号

时间:2013-01-18 21:52:13

标签: clojure

我一定是误解了如何定义函数。我正在做这个SICP练习,“定义一个过程,它接受三个数字作为参数,并返回两个较大数字的平方和。”

我在REPL中尝试这个,它似乎有效:

=> (reduce + (map (fn [x] (* x x)) (rest (sort '(2 1 0)))))
5

但是定义一个过程并用参数替换数字会给我一个错误:

=> (defn my-procedure [a b c] (reduce + (map (fn [x] (* x x)) (rest (sort '(a b c))))))
ClassCastException clojure.lang.Symbol cannot be cast to java.lang.Number clojure.lang.Numbers.multiply (Numbers.java:146)

我没看到什么?谢谢!

2 个答案:

答案 0 :(得分:1)

这应该适合你:

(defn my-procedure [a b c]
  (reduce + (map (fn [x] (* x x)) (rest (sort (list a b c))))))

这就是为什么:

使用quote form时,不会评估表单,也不会解析您的变量。在你的情况下,你留下一个符号列表。

user=> (def a 1)
#'user/a
user=> '(a)
(a)
user=> (list a)
(1)
user=> `(a) ;; backtick causes vars to be namespace qualified
(user/a)
user=> (class (first '(a)))
clojure.lang.Symbol

您应该使用list函数或其他集合

,而不是创建未评估的表单
user=> [a] ;; vector
[1]
user=> #{a} ;; set
#{1}

;; (defn sum-of-squares [& args]
;;   (apply + (map #(* % %) args)))

答案 1 :(得分:0)

自动将函数的参数放在集合中:

(defn foo [& x]
  (reduce + (map #(* % %) (rest (sort x)))))