Ich habe in Clojure Folgendes versucht und erwartet, dass die Klasse einer nicht faulen Sequenz zurückgegeben wird:
(.getClass (doall (take 3 (repeatedly rand))))
Dies kehrt jedoch immer noch zurück clojure.lang.LazySeq
. Ich vermute, dass doall
die gesamte Sequenz ausgewertet wird, aber die ursprüngliche Sequenz zurückgegeben wird, da sie für das Auswendiglernen immer noch nützlich ist.
Was ist also das idiomatische Mittel, um aus einer faulen eine nicht faule Sequenz zu erstellen?
clojure
lazy-evaluation
Tim Clemons
quelle
quelle
doall
(vec (take 3 (repeatedly rand)))
Antworten:
doall
ist alles, was du brauchst. Nur weil derseq
Typ has hat,LazySeq
heißt das nicht, dass eine Auswertung ansteht. Lazyseq
s speichert ihre Ergebnisse im Cache. Alles, was Sie tun müssen, ist, die Faulenseq
einmal (wiedoall
auch) zu gehen, um alles zu erzwingen und sie somit nicht faul zu machen.seq
erzwingt nicht die Auswertung der gesamten Sammlung.quelle
realized?
.realize
passende Operation gebenrealized?
.contains?
egal ist, ob Sie die Lazy Seq erkannt haben oder nicht, beantwortet dies die spezifische Frage wie gestellt, aber weniger den Titel der Frage.Dies ist bis zu einem gewissen Grad eine Frage der Taxonomie. Eine faule Sequenz ist nur eine Art von Sequenz, ebenso wie eine Liste, ein Vektor oder eine Karte. Die Antwort lautet natürlich: "Es hängt davon ab, welche Art von nicht fauler Sequenz Sie erhalten möchten:
Treffen Sie Ihre Wahl aus:
(doall ... )
(apply list (my-lazy-seq)) OR (into () ...)
(vec (my-lazy-seq))
Sie können jede Art von Sequenz wählen, die Ihren Anforderungen am besten entspricht.
quelle
(vec (my-lazy-seq))
ist nicht so schön in Situationen wie den folgenden:(vec (json/parse-string "{\"foo\":\"bar\"}")) ;; => [["foo" "bar"]]
Dacheshire
beschließt, eine Lazy-Seq von(json/parse-string)
(json/parse-string-strict)
Dieser reiche Typ scheint seine Clojure zu kennen und hat absolut Recht.
Aber ich denke, dieses Code-Snippet könnte anhand Ihres Beispiels eine nützliche Ergänzung zu dieser Frage sein:
In der Tat hat sich der Typ nicht geändert, aber die Verwirklichung hat sich geändert
quelle
realized?
zurückzukehrentrue
. ZB(let [r (range) r? (realized? r)] (doall (take 1 r)) [r? (realized? r)]) => [false true]
[true true]
Ich bin auf diesen Blog- Beitrag gestoßen,
doall
weil ich nicht rekursiv bin. Dafür fand ich, dass der erste Kommentar im Beitrag den Trick machte. Etwas in der Art von:Ich fand dies nützlich in einem Komponententest, bei dem ich die Auswertung einiger verschachtelter Anwendungen
map
erzwingen wollte , um eine Fehlerbedingung zu erzwingen.quelle
quelle