Comment puis-je exécuter une fonction avec des effets secondaires plus d'un vecteur?
-
02-01-2020 - |
Question
L'-dis bonjour à la première personne, qui fonctionne bien, pourquoi ne pas dire bonjour à tout le monde?
(defpartial greeting [name] [:p.alert "Hello " name ", how are you?"]) (defn say-hello [name] (append $content (greeting name))) (defn say-hello-to-first-person [names] (say-hello (first names))) (defn say-hello-to-everyone [names] (map say-hello names)) (say-hello-to-first-person ["Chris" "Tom" "Jim" "Rocky"]) (say-hello-to-everyone ["Chris" "Tom" "Jim" "Rocky"])
La solution
Vous voulez doseq
, Clojure est "foreach":
(doseq [name names]
(say-hello name))
map
ne fonctionne pas, car il produit un paresseux de la séquence:Jusqu'à ce que vous avez réellement accéder aux éléments de la séquence (dont vous ne faites pas ici), aucun d'entre eux seront évalués, et les effets secondaires ne se produisent.
Une autre option est de forcer l'évaluation par emballage dorun
autour de la map
.La réflexion sur pourquoi cela fonctionne peut aider votre compréhension (bien que doseq
est le idiomatiques approche ici).
Autres conseils
Comme @edbond dit dans son commentaire, carte FN n'ayant pas évalué avant le moment nécessaire car la carte de la carte retourne un SEQ paresseux.
Ceci est le doc de carte fn Renvoie une séquence paresseuse composée du résultat de l'application de f vers le ensemble de premiers éléments de chaque Coll, suivi d'appliquer F à l'ensemble de second articles dans chaque Coll, jusqu'à ce que l'un des Colls soit épuisé.Tous les articles restants dans d'autres Colls sont ignorés.Une fonction f devrait accepter les arguments du nombre de Colls.
Si vous devez être sûr que les valeurs sont évaluées dans une partie spécifique de votre code, vous pouvez utiliser Dotall ou Dorun