Bei Verwendung von reduce
gibt es die reductions
Funktion, um die Liste der aufeinanderfolgenden Reduzierungen anzuzeigen. Gibt es etwas Ähnliches Debug loop
in Clojure?clojure loop siehe Werte
Antwort
@progo ist richtig, Sie können immer einen weiteren Akkumulator hinzufügen, aber wenn Sie es nicht wirklich jedes Mal tun möchten, könnten Sie einige Makros machen, die für Sie semantisch dem Standard loop/recur
entsprechen (ich denke an zwei loop+/recur+
(letztere implizit verwendet werden würde):
(defmacro recur+ [& args]
(let [names (repeatedly (count args) gensym)]
`(let ~(vec (interleave names args))
(recur [email protected] (conj ~'&loop-history [[email protected]])))))
(defmacro loop+ [bindings & body]
(let [val-names (repeatedly (/ (count bindings) 2) gensym)
vals (take-nth 2 (rest bindings))
binding-lefts (take-nth 2 bindings)]
`(let [[email protected](interleave val-names vals)]
(loop [[email protected](interleave binding-lefts val-names)
~'&loop-history [~(vec val-names)]]
[email protected](clojure.walk/postwalk-replace
{'recur 'recur+
'loop 'loop+}
body)))))
wie Sie sehen können, loop+
führt den impliziten Wert &loop-history
und ersetzt alle inneren loop
s und recur
s mit loop+
und recur+
, während recur+
fügt diese implizite var derhinzuAnruf (der Teil mit val-names
, vals
und binging-lefts
ist wesentlich, um die doppelte Bewertung der Formulare zu vermeiden, die an die loop+
übergeben werden).
so, stellen Sie sich eine Schleife wie dieses:
user> (loop [a 1 b 2]
(if (<= b 10)
(recur a (inc b))
(str a " " b)))
"1 11"
die neue Schleife verwenden nur Schleife aufrufen + statt Schleife:
user> (loop+ [a 1 b 2]
(if (<= b 10)
(recur a (inc b))
(str a " " b)))
"1 11"
es in den folgenden erweitert wird:
(let*
[G__20054 1 G__20055 2]
(loop*
[a G__20054 b G__20055 &loop-history [[G__20054 G__20055]]]
(if (<= b 10)
(let*
[G__20056 a G__20057 (inc b)]
(recur
G__20056
G__20057
(conj &loop-history [G__20056 G__20057])))
(str a " " b))))
jetzt &loop-history
ist überall zugänglich innerhalb der Schleife +:
user> (loop+ [a 1 b 2]
(if (<= b 10)
(do
(println "history length: " (count &loop-history)
"last item: " (last &loop-history))
(recur a (inc b)))
{:result (str a " " b)
:history &loop-history}))
;; history length: 1 last item: [1 2]
;; history length: 2 last item: [1 3]
;; history length: 3 last item: [1 4]
;; history length: 4 last item: [1 5]
;; history length: 5 last item: [1 6]
;; history length: 6 last item: [1 7]
;; history length: 7 last item: [1 8]
;; history length: 8 last item: [1 9]
;; history length: 9 last item: [1 10]
;; {:result "1 11", :history [[1 2] [1 3] [1 4] [1 5] [1 6] [1 7] [1 8] [1 9] [1 10] [1 11]]}
Ankündigung, dass es führt auch &loop-history
für innere Schleifen, ohne die Notwendigkeit, den Quellcode zu ändern:
user> (loop+ [a 1 b 2]
(if (<= b 10)
(do (println :outer-hist &loop-history)
(recur a (inc b)))
(loop [a a]
(if (>= a -4)
(do (println :inner-hist &loop-history)
(recur (dec a)))
(str a b)))))
:outer-hist [[1 2]]
:outer-hist [[1 2] [1 3]]
:outer-hist [[1 2] [1 3] [1 4]]
:outer-hist [[1 2] [1 3] [1 4] [1 5]]
:outer-hist [[1 2] [1 3] [1 4] [1 5] [1 6]]
:outer-hist [[1 2] [1 3] [1 4] [1 5] [1 6] [1 7]]
:outer-hist [[1 2] [1 3] [1 4] [1 5] [1 6] [1 7] [1 8]]
:outer-hist [[1 2] [1 3] [1 4] [1 5] [1 6] [1 7] [1 8] [1 9]]
:outer-hist [[1 2] [1 3] [1 4] [1 5] [1 6] [1 7] [1 8] [1 9] [1 10]]
:inner-hist [[1]]
:inner-hist [[1] [0]]
:inner-hist [[1] [0] [-1]]
:inner-hist [[1] [0] [-1] [-2]]
:inner-hist [[1] [0] [-1] [-2] [-3]]
:inner-hist [[1] [0] [-1] [-2] [-3] [-4]]
"-511"
loop
/recur
ist zwingend erforderlich als reductions
; Sie können sehr gut nur Ihre eigene Protokollierung in den Schleifenkörper selbst einfügen oder eine Atomliste von Werten beibehalten oder, am funktionalsten, einen (anderen) Akkumulator in die Schleifenargumente einführen.
- 1. Loop Werte ersetzen
- 2. Bash Scripting - Nested Loop-Punkt falsche Werte
- 3. PHP Siehe, wenn alle Werte im Array String enthalten
- 4. Clojure ständig und Kartenfunktion
- 5. Siehe Controller-Submodul AngularJS
- 6. jquery - siehe spezifisches Formular
- 7. Siehe Projektabhängigkeiten von MSBuild
- 8. Siehe Navigationsleiste Vorschau
- 9. Siehe die Variable
- 10. Loop-Modul für Node.js
- 11. Enhanced For Loop Exception
- 12. Clojure - Rekursiv plätten Verschachtelte Maps
- 13. aktualisieren Werte in einem Vektor von Karten in clojure
- 14. Clojure: Testen aller Werte von Kartenoperation auf Wahrheit
- 15. anhängen Werte in einer globalen Karte in clojure
- 16. Clojure/Java Mandelbrot Fraktalzeichnung
- 17. Matrixtransposition in clojure
- 18. wie man String zwischen [LOOP] ... [/ LOOP]
- 19. Loop Mocha Tests?
- 20. Verbesserung meines ersten Clojure-Programms
- 21. Siehe geerbt Dokumentation in PhpStorm
- 22. Siehe Capistrano vorige Revision Zeitstempel
- 23. RVM siehe Edelsteine in Gemset
- 24. siehe "send mail" mit sendmail
- 25. Siehe Thread nicht korrekt beendet
- 26. Siehe letzte Änderungen in SVN
- 27. Siehe Generierte Abfrage mit Phantom
- 28. Siehe Anmerkungen in Scala Reflexion
- 29. PHP/jQuery Paginierung Siehe System-
- 30. Siehe Enum innerhalb einer Struktur
Hat es eine faule Sequenz zurückkehren wie 'reductions' tut? –