我正在尝试一些clojure的示例。
(def sum #(reduce + %))
(def avg #(/ (sum %) (count %)))
(defn stats
[numbers]
(map #(% numbers) '(sum, avg)) ;;works when it is [sum avg]
)
当我调用统计功能
时 (stats [1 24 235 34511 0 14])
它返回(nil nil)
。但是,如果我更改评论中提到的代码,它将返回预期的输出。
(34785 11595/2)
为什么不能将函数传递为列表?
您可以将集合参数中的函数传递给 map
,但是示例中的 '
前缀是引用 ,因此内容是符号 sum
和 avg
而不是 values 。
'(sum avg) ;; quoted list, contents are symbols
'[sum avg] ;; quoted vector, contents are symbols
(list sum avg) ;; list of the functions, using `list` fn to create a list
[sum avg] ;; vector of the functions
'
是quote
的速记。
未引用的列表文字经过专门处理。Clojure将无引用的列表解释为召唤,其中列表中的第一个元素是指被调用的内容。例如,这将调用sum
函数,将avg
函数作为其第一个参数(将行不通):
(sum avg)
通过 map
ping type
函数通过引用和未引用的列表,我们可以看到列表元素类型的差异:
user=> (map type '(conj assoc))
(clojure.lang.Symbol clojure.lang.Symbol) ;; symbols
user=> (map type (list conj assoc))
(clojure.core$conj__5112 clojure.core$assoc__5138) ;; fn values
这是引用的另一个广泛答案:在clojure中使用引用