Skip to content

Commit 1d47714

Browse files
Merge pull request #492 from sebastiano-barrera/eduction
Add `eduction` and `completing`
2 parents ba28b85 + 2789b87 commit 1d47714

File tree

2 files changed

+52
-0
lines changed

2 files changed

+52
-0
lines changed

pixie/stdlib.pxi

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1884,6 +1884,35 @@ not enough elements were present."
18841884
(when-let [s (seq coll)]
18851885
(reductions f (f init (first s)) (rest s))))))))
18861886

1887+
(defn completing
1888+
"Takes a reducing function f of 2 args and returns a fn suitable for
1889+
transduce by adding an arity-1 signature that calls cf (default -
1890+
identity) on the result argument."
1891+
([f] (completing f identity))
1892+
([f cf]
1893+
(fn
1894+
([] (f))
1895+
([x] (cf x))
1896+
([x y] (f x y)))))
1897+
1898+
(deftype Eduction [xform coll]
1899+
IReduce
1900+
(-reduce [self f init]
1901+
;; NB (completing f) isolates completion of inner rf from outer rf
1902+
(transduce xform (completing f) init coll))
1903+
1904+
ISeqable
1905+
(-seq [self]
1906+
(reduce conj self)))
1907+
1908+
(defn eduction
1909+
"Returns a reducible/iterable application of the transducers
1910+
to the items in coll. Transducers are applied in order as if
1911+
combined with comp. Note that these applications will be
1912+
performed every time reduce/iterator is called."
1913+
[& xforms]
1914+
(->Eduction (apply comp (butlast xforms)) (last xforms)))
1915+
18871916
(defn destructure [binding expr]
18881917
(cond
18891918
(symbol? binding) [binding expr]

tests/pixie/tests/test-stdlib.pxi

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -574,6 +574,29 @@
574574
(t/assert= (take 5 (cycle '(1 2))) '(1 2 1 2 1))
575575
(t/assert= (take 3 (cycle [nil])) '(nil nil nil)))
576576

577+
(t/deftest test-eduction
578+
;; one xform
579+
(t/assert= [1 2 3 4 5]
580+
(eduction (map inc) (range 5)))
581+
;; multiple xforms
582+
(t/assert= ["2" "4"]
583+
(eduction (map inc) (filter even?) (map str) (range 5)))
584+
;; materialize at the end
585+
(t/assert= [1 1 2 1 2 3 1 2 3 4]
586+
(vec (->> (range 5)
587+
(eduction (mapcat range) (map inc)))))
588+
(t/assert= {1 4, 2 3, 3 2, 4 1}
589+
(->> (range 5)
590+
(eduction (mapcat range) (map inc))
591+
frequencies))
592+
(t/assert= ["tac" "god" "hsif" "drib" "kravdraa"]
593+
(->> ["cat" "dog" "fish" "bird" "aardvark"]
594+
(eduction (map pixie.string/reverse))
595+
(seq)))
596+
;; expanding transducer with nils
597+
(t/assert= '(1 2 3 nil 4 5 6 nil)
598+
(eduction cat [[1 2 3 nil] [4 5 6 nil]])))
599+
577600
(t/deftest test-trace
578601
(try
579602
(/ 0 0)

0 commit comments

Comments
 (0)