将函数列表传递给 clojure 中的 'map' 将给出 nil



我正在尝试一些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,但是示例中的 '前缀是引用 ,因此内容是符号 sumavg而不是 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中使用引用

最新更新