如何将函数作为参数传递

时间:2014-10-25 00:07:39

标签: clojure functional-programming

我有一个接收矢量并对所有元素求和的函数。

(def rec
  (fn [numbers acc]
    (if (empty? numbers)
      acc
      (recur (rest numbers) (+ acc (first numbers))))))
(prn (rec [1 2 3] 0))

但不是调用函数" +"我想将操作作为参数传递,这意味着,我想将一个函数作为参数传递,然后调用该函数。

我试过了:

(def rec
  (fn [f numbers acc]
    (if (empty? numbers)
      acc
      (recur (rest numbers) (f acc (first numbers))))))
(prn (rec + [4 2 1] 0))

但它不起作用,我知道有更好的方法来对矢量中的数字求和,但我从功能开始,所以进行这种练习很重要。

提前致谢。

3 个答案:

答案 0 :(得分:1)

您需要使用与参数向量相同的参数重复,在这种情况下:

(recur f (rest numbers) (f acc (first numbers))))))

(顺便说一下,使用defn来定义函数的标准是(defn f[x] ... )(def f (fn [x] ...)))更简洁

答案 1 :(得分:0)

更多的意识形态Clojure会在这里使用reduce,我想

(defn rec [f numbers acc]
  (reduce f acc numbers))

(rec + [1 2 3] 0)
# 6

答案 2 :(得分:0)

在你的

(def rec
  (fn [numbers acc]
    (if (empty? numbers)
      acc
      (recur (rest numbers) (+ acc (first numbers))))))

...您可以将累加器acc推到rec

的表面下方
(defn rec [numbers]
  (loop [ns numbers, acc 0]
    (if (empty? ns)
      acc
      (recur (rest ns) (+ acc (first ns))))))

例如,

(rec + [1 3])
; 4

如果要将操作作为参数传递,则约定是使用 no 参数调用它给出其标识:当它返回另一个参数时返回的值适用于两个。

因此

(+) ; => 0
(*) ; => 1

因此我们可以将您的参数化rec写为

(defn rec [op numbers]
  (loop [ns numbers, acc (op)]
    (if (empty? ns)
      acc
      (recur (rest ns) (op acc (first ns))))))

这几乎是reduce的工作原理,尽管并不像IMO那样优雅。