Как заставить функцию Clojure принимать переменное количество параметров?


Я изучаю Clojure и пытаюсь определить функцию, которая принимает переменное число параметров (a variadic функция) и суммировать их (да, так же, как + процедура). Однако, я не знаю, как реализовать такую функцию

все, что я могу сделать, это:

(defn sum [n1, n2] (+ n1 n2))

конечно эта функция принимает два параметра и только два параметра. Пожалуйста, научите меня, как заставить его принять (и обработать) неопределенное количество параметры.

5 73

5 ответов:

в общем случае некоммутативный случай можно использовать применить:

(defn sum [& args] (apply + args))

поскольку сложение коммутативно, что-то вроде этого тоже должно работать:

(defn sum [& args] (reduce + args))

& причины args быть привязанным к остальной части списка аргументов (в этом случае весь список, так как слева от &).

очевидно, определение суммы, как это не имеет смысла, так как вместо:

(sum a b c d e ...)

вы можете просто напишите:

(+ a b c d e ....)

Yehoanathan упоминает перегрузку арности, но не дает прямого примера. Вот о чем он говорит:

(defn special-sum
  ([] (+ 10 10))
  ([x] (+ 10 x))
  ([x y] (+ x y)))

(special-sum) =>20

(special-sum 50)=>60

(special-sum 50 25)=>75

 (defn my-sum
  ([]  0)                         ; no parameter
  ([x] x)                         ; one parameter
  ([x y] (+ x y))                 ; two parameters
  ([x y & more]                   ; more than two parameters


    (reduce + (my-sum x y) more))
  )

defn это макрос, который делает определение функций немного проще. Clojure поддерживает перегрузку arity в одном объекте функции, само-ссылка и функции переменной арности с использованием &

от http://clojure.org/functional_programming

(defn sum [& args]
  (print "sum of" args ":" (apply + args)))

Это принимает любое количество аргументов и добавить их.