web-dev-qa-db-fra.com

Comment faire qu'une fonction Clojure prenne un nombre variable de paramètres?

J'apprends Clojure et j'essaie de définir une fonction qui prend un nombre variable de paramètres (une fonction variadic) et les résume (oui, tout comme la procédure +). Cependant, je ne sais pas comment implémenter une telle fonction

Tout ce que je peux faire c'est:

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

Bien entendu, cette fonction ne prend que deux paramètres et deux paramètres. Veuillez m'apprendre comment faire accepter (et traiter) un nombre indéfini de paramètres.

77
rodrigoalves

En général, cas non commutatif, vous pouvez utiliser appliquer :

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

Puisque l'addition est commutative, quelque chose comme ça devrait aussi fonctionner:

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

& oblige args à être lié au reste de la liste d'arguments (dans ce cas, la liste entière, car il n'y a rien à gauche de &).

De toute évidence, définir une telle somme n'a pas de sens, car au lieu de:

(sum a b c d e ...)

vous pouvez simplement écrire:

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

Yehoanathan mentionne une surcharge en nombre mais ne fournit pas d'exemple direct. Voici de quoi il parle:

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

(special-sum) => 20

(special-sum 50) => 60

(special-sum 50 25) => 75

30
Devin Walters
 (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))
  )
17
hariszaman

defn est une macro qui rend la définition des fonctions un peu plus simple. Clojure prend en charge la surcharge d'arité dans un objet de fonction unique, les fonctions d'auto-référence et d'arité variable à l'aide de &

De http://clojure.org/functional_programming

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

Cela prend un certain nombre d'arguments et les additionne.

3
amirt