Z nowym clojure 1.7 postanowiłem zrozumieć, gdzie mogę używać przetworników. Rozumiem, jakie korzyści mogą dać, ale nie mogę znaleźć normalnych przykładów pisania niestandardowych przetworników z wyjaśnieniem.Zachowanie przetworników Clojure
OK, próbowałem sprawdzić, co się dzieje. Otworzyłem dokumentację clojure. I tam przykłady używają xf
jako argumentu. Po pierwsze: co oznacza ten xf lub xfrom? To wszystko wyprodukowało przetwornik tożsamości.
(defn my-identity [xf]
(fn
([]
(println "Arity 0.")
(xf))
([result]
(println "Arity 1: " result " = " (xf result))
(xf result))
([result input]
(println "Arity 2: " result input " = " (xf result input))
(xf result input))))
Nazwałam zmienne [result input]
z przykładu dokumentacji. Myślałem, że to jest jak w funkcji zmniejszania, gdzie result
jest zredukowaną częścią, a input
jest nowym elementem kolekcji.
Kiedy otrzymałem (transduce my-identity + (range 5))
otrzymałem wynik 10
, którego oczekiwałem. Potem czytałem o eduction
, ale nie mogę zrozumieć, co to jest. Zresztą zrobiłem (eduction my-identity (range 5))
i otrzymała:
Arity 2: nil 0 = nil
Arity 2: nil 1 = nil
Arity 1: nil = nil
(0 0 1 1)
Każdy element został powielony dlatego wzywam xf
w println
oświadczeniu. Dlaczego dwukrotnie powielono każdy przedmiot? Dlaczego mam zero? Czy zawsze otrzymam zero podczas dokonywania edycji? Czy mogę przekazać na to zachowanie?
Zresztą zrobiłem
> (reduce + (eduction my-identity (range 5))
clojure.core.Eduction cannot be cast to clojure.lang.IReduce
Ok, wynik jest Eduction
że nie sprowadza się, ale drukowane jak liście. Dlaczego nie można go zredukować? Po wpisaniu (doc eduction)
otrzymuję że
Returns a reducible/iterable application of the transducers
to the items in coll.
nie powinno (transduce xform f coll)
i (reduce f (eduction xfrom coll))
być takie same?
zrobiłem
> (reduce + (sequence my-identity (range 5))
20
Oczywiście dostałam 20
ponieważ duplikatów. Znowu pomyślałem, że powinno to być i (reduce f (sequence xfrom coll))
być zawsze równe co najmniej w tak małym przykładzie bez jakichkolwiek przetworników stanu. To głupie, że oni nie są, czy ja się mylę?
Ok, następnie próbowałem (type (sequence my-identity (range 5)))
i dostać clojure.lang.LazySeq pomyślałem, że to jest leniwy, ale gdy próbowałem wziąć first
elementu Clojure oblicza wszystkie sekwencję naraz.
Więc moje podsumowanie:
1) Co oznacza XF lub xform?
2) Dlaczego otrzymuję nil
jako argument result
podczas eduction
lub sequence
?
3) Czy mogę zawsze być pewien, że będzie to nil
podczas eduction
lub sequence
?
4) Co to jest eduction
i jaki jest idiomatyczny pomysł, że nie można go zredukować? A jeśli tak, to jak mogę to zmniejszyć?
5) Dlaczego dostaję efekty uboczne podczas sequence
lub eduction
?
6) Czy mogę tworzyć rzeczywiste, leniwe sekwencje z przetwornikami?
1) [clojure.org/transducers](http://clojure.org/transducers) - „Przetwornik XF jest stosem transformacja ... "; tak więc xf jest przetwornikiem (lub kompsem xfs), który nie jest funkcją (f), więc jeden nazywa go 'xf' – birdspider
1) edit: powinien był to sformułować jako" i odróżnić go od zwykłej funkcji (f) jeden nazywa to 'xf' ' – birdspider
Masz tu bardzo interesujące pytania, ale myślę, że uzyskasz więcej lepszych odpowiedzi, jeśli wydasz na nie mniejsze pytania. Pytanie "1" może być oddzielnym pytaniem ("Jakie jest znaczenie xf lub xform w kontekście przetworników?"), Nie wymaga nawet przykładu, to samo dotyczy pytań 4 i 6. – nberger