Je tiens à appliquer à plusieurs reprises une fonction à un état jusqu'à ce qu'une condition contienne true.
Fonction F prend un état, la modifie et le renvoie. Appliquez F à nouveau à l'état retourné et ainsi de suite. P>
Je pense que cela fonctionnerait. P>
(loop [f x p] (if (p x) x (recur f (f x) p))
6 Réponses :
Vous ne savez pas ce que vous voulez dire par itérateur code> - vous l'utilisez comme s'il était itérer code>, et je veux juste être sûr que c'est ce que tu veux dire. En tout cas, votre solution me semble bien et pas du tout laide. Et la mémoire n'est pas une question non plus: itérer code> est libre de jeter les résultats intermédiaires chaque fois que ce n'est pas pratique, car vous n'en gardez pas de références, appelez simplement filtre code> une manière "streaming". p>
Oui, je voulais dire itérer. C'était une faute de frappe. Mais cela a du sens. J'ai couru cela de sorte que Prey est toujours retourné vrai et je ne reçois pas une exception de mémoire hors mémoire.
On dirait que vous voulez que le http://richhickey.github.com/ clojure / clojure.core-api.html # clojure.core / tandis que p>
Utilisation: (Pendant le test et le corps)
Exécute à plusieurs reprises du corps pendant que l'expression de test est vraie. Présumer
Un certain effet secondaire provoquera un test de faux / nil. Retourne nil p>
blockQuote>
Dans un cas d'utilisation légèrement différent, le http://richhickey.github.com/ clojure / clojure.core-api.html # clojure.core / pour p>
Utilisation: (pour SEQ-EXPRS Body-Expr)
Compréhension de la liste. Prend un vecteur d'un ou plusieurs
Formulaire de liaison / collection-Expr paires, chacun suivi de zéro ou plus
modificateurs et donne une séquence paresseuse d'évaluations d'EXPR.
Les collections sont itélées à une mode imbriquée, le plus rapide le plus rapide,
et Coll-Expres imbriqués peut se référer aux liaisons créées dans l'avant
formes de liaison. Les modificateurs pris en charge sont les suivants:: Laissez [formulaire de liaison expr ...],
: En test, lors de l'essai. P>
(prendre 100 (pour [x (gamme 100000000) Y (plage 1000000): tandis que ( pendant code> macro. p>
pour code> macro prend en charge: Quand et: tandis que les options. P>
Pas sûr de ce que cela nécessite un effet secondaire. N'a pas pensé à cela, mais pour le fonctionnement, mais vous utiliseriez toujours ITHÉTER (premier (pour [z (itérer f x): tandis que (PRED Z))
Regardez la source de pendant code> et vous verrez que c'est très comme ce que vous voudriez coder à la main. N'oubliez pas que les données sont immuables dans le clojure, de sorte que «un effet secondaire» dans ce cas pourrait simplement être une mise à jour de l'état de var x.
Ce que vous voulez vraiment, c'est : modifier p> Un moyen d'utiliser des fonctions d'ordre supérieur pour obtenir le résultat que vous souhaitez consister à envelopper votre fonction à quelque chose à consommer par < Code> trampoline code>, nommément une fonction qui renvoie le résultat final ou une autre fonction qui exécutera la prochaine étape. Voici le code: p> L'exécution itérative irait comme suit: p>
Je ne pense pas qu'il y ait une fonction de base qui le fait exactement et efficace. Par conséquent, je le ferais avec une boucle / recur comme suit: boucle / recur est très efficace car il ne nécessite aucun stockage supplémentaire et est implémenté comme une boucle simple dans la JVM. P> Si vous allez le faire beaucoup, vous pouvez toujours encapsuler le motif dans une macro. p> p>
Je suis d'accord avec votre réponse, sauf que cela n'a pas besoin d'être une macro? Une simple fonction récursive fonctionnerait également aussi bien?
@dbryne Bien sûr - vous pouvez aussi faire une fonction si vous le souhaitez. Bien que dans ce cas, je pense que je préférerais une macro - vous obtiendriez une efficacité d'exécution légèrement meilleure, et j'ai tendance à préférer les macros pour tout ce qui ressemble à une "structure de contrôle".
Je conviens que c'est la solution la plus efficace. Et c'est ce que j'aurais fait si ce n'était pas juste pour la pratique. Un avantage est qu'il est facile de raisonner sur la performance. Si cela était quelque chose que j'allais utiliser beaucoup, j'utiliserais une fonction. Je pense que ce type de fonction pourrait être inlincé par la JVM, donc je ne sais pas pourquoi vous voudriez utiliser une macro.
Je pense que vous devriez simplement faire une boucle une fonction récursive simple:
Oui, bien sûr, c'est une bonne solution. Mais il est bon de pratiquer l'utilisation des fonctions d'ordre supérieur dans la bibliothèque principale à une récursion abstraite abstraite. Au fait, j'appellerais cela, jusqu'à ce que. Ce serait bien d'avoir quelque chose comme celui-ci dans la bibliothèque principale.
Que diriez-vous de supprimer
(first (drop-while (comp not pred) (iterate f x))