EDIT: ALLES ich geschrieben habe UNRECHT
Wenn eine Funktion mit einem var-arg wird mit einer Sequenz angewendet, die länger ist als die Anzahl diskreter Argumente, der Rest der Sequenz wird als var-arg übergeben (siehe RestFn.applyTo).
Zu Jürgen: Ich bin dumm. Du bist schlau. Ich habe mich geirrt. Du hattest Recht. Du bist der beste. Ich bin der Schlechteste. Du siehst sehr gut aus. Ich bin nicht attraktiv.
Das Folgende ist eine Abspeicherung meiner Idiotie ...
Als Reaktion auf Jürgen Hötzel Kommentar.
mapcat
ist nicht vollständig faul, weil apply
ist nicht faul bei der Beurteilung der Anzahl der anzuwendenden Argumente. Ferner kann apply
nicht faul sein, weil Funktionen mit einer diskreten Anzahl von Argumenten aufgerufen werden müssen. Derzeit, wenn die Anzahl der Argumente 20 überschreitet, werden die verbleibenden Argumente in ein Array ausgegeben, daher nicht faul.
sucht also an der Quelle für mapcat
:
(defn mapcat
"Returns the result of applying concat to the result of applying map
to f and colls. Thus function f should return a collection."
{:added "1.0"}
[f & colls]
(apply concat (apply map f colls)))
Wenn wir die Auswertung aus am Beispiel die inneren apply
würde beurteilen zu erweitern:
user=> (map seq str-coll)
((\a \b \c \d) (\e \f \g \h) (\j \k \l \m))
die seit dem str-coll
doesn ist in Ordnung werde nicht vollständig realisiert, aber dann würde der äußere apply
zu bewerten:
user=> (concat '(\a \b \c \d) '(\e \f \g \h) '(\j \k \l \m))
(\a \b \c \d \e \f \g \h \j \k \l \m)
Beachten Sie, dass die äußere apply
gilt n Argumente zu concat
, eine für jede Zeichenfolge in der ursprünglichen str-coll
. Nun, es ist wahr, dass das Ergebnis von concat
faul ist, und jeder arg ist selbst faul, aber Sie müssen noch die volle Länge von str-coll
zu bekommen, um diese n Lazy Seqs zu bekommen. Wenn str-coll
1000 Zeichenfolgen hat, dann erhält concat
1000 Argumente, und alle 1000 Zeichenfolgen müssten aus der Datei ausgelesen und in den Speicher geladen werden, bevor concat
aufgerufen werden kann.
Für The Unbelievers, eine Demonstration der Seq-Realisierung Verhalten gelten:
user=> (defn loud-seq [] (lazy-seq (println "HELLO") (cons 1 (loud-seq))))
#'user/loud-seq
user=> (take 3 (loud-seq)) ; displaying the lazy-seq realizes it, thus printing HELLO
(HELLO
HELLO
1 HELLO
1 1)
user=> (do (take 3 (loud-seq)) nil) ; lazy-seq not realized; no printing of HELLO
nil
user=> (do (apply concat (take 3 (loud-seq))) nil) ; draw your own conclusions
HELLO
HELLO
HELLO
nil
Und eine Demonstration, dass varargs sind nicht faul:
user=> (defn foo [& more] (type more))
#'user/foo
user=> (foo 1 2 3 4)
clojure.lang.ArraySeq
user=> (apply foo (repeat 4 1))
clojure.lang.Cons
Obwohl als Kontrapunkt, dass die folgenden Arbeiten verwirren mich:
user=> (take 10 (apply concat (repeat [1 2 3 4])))
(1 2 3 4 1 2 3 4 1 2)
Keine Notwendigkeit zu flachen, nur die Zeichenfolgen mit mapcat: (Partition-alle 3 (mapcat seq str-coll)) –
ataggart und Jürgen, vielen Dank für die Lösungen: Mapping zu einem Seq war genau das, was ich war fehlt. Die Überwindung dieser Hürde ließ mich erkennen, dass die Partitionierung nicht so träge wirkte, wie ich es mir erhofft hatte. Während jede Partition auf eine faule Weise bereitgestellt wird, sind die einzelnen Komponenten jeder Partition nicht; Das Partitionieren der Anfangsdatei bei Trennzeichen stellt daher nicht die gewünschten Lazy-Strings bereit, die in dieses Feld eingefügt werden. –
@ Jürgen: mapcat ist nicht faul (es verwendet apply), weshalb ich es nicht verwendet habe. –