Last active
August 29, 2015 14:05
-
-
Save ithayer/98221873f2444409a318 to your computer and use it in GitHub Desktop.
Transducers Examples
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
;; Example of reducing fn that computes sufficient | |
;; statistics for a mean. | |
=> (defn mean-reducer [memo x] | |
(-> memo | |
(update-in [:sum] + x) | |
(update-in [:count] inc))) | |
=> (reduce mean-reducer {:sum 0 :count 0} (range 10)) | |
{:count 10, :sum 45} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
;; A crude "transducer" that accepts a reducing function 'f1' | |
;; and returns a new reducing function that will have | |
;; 'input' incremented. | |
=> (defn increment-transducer [f1] | |
(fn [result input] ;; A transducer returns a reducing fn. | |
(f1 result ;; That reducing fn will still call 'f1', | |
(inc input)))) ;; but only after it increments the input. | |
=> (reduce (increment-transducer mean-reducer) | |
{:sum 0 :count 0} | |
(range 10)) | |
{:count 10, :sum 55} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
;; Source of the new arity of the 'map' function. | |
(defn map | |
([f] ;; When called with a single argument, | |
(fn [f1] ;; map returns a transducer that accepts a reducing function. | |
(fn ;; Like our crude transducer, this transducer returns | |
;; a reducing function, | |
([] (f1)) | |
([result] (f1 result)) | |
([result input] ;; and this arity does the same as what ours did. | |
(f1 result (f input))) | |
([result input & inputs] | |
(f1 result (apply f input inputs)))))) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
;; No need for an explicit 'increment-transducer' function, it | |
;; can be created by 'map'. | |
=> (reduce ((map inc) mean-reducer) | |
{:sum 0 :count 0} | |
(range 10)) | |
{:count 10, :sum 55} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
;; Same result without transducers. | |
=> (->> (range 10) | |
(map inc) | |
(reduce mean-reducer | |
{:sum 0 :count 0})) | |
{:count 10, :sum 55} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
;; Some examples from the launch announcement. | |
;; Use 'sequence' to return a new transduced sequence. | |
=> (sequence (map inc) (range 10)) | |
(1 2 3 4 5 6 7 8 9 10) | |
;; Use 'transduce' like 'reduce'. | |
=> (transduce (map inc) mean-reducer {:sum 0 :count 0} (range 10)) | |
{:count 10, :sum 55} | |
;; Note that one important difference between 'transduce' and 'reduce' | |
;; is the behavior when an initial value is not passed. | |
;; 'transduce' - calls the reducing function (eg: 'mean-reducer' above) | |
;; with no args to generate the initial value | |
;; 'reduce' - starts the reducing function on the first two values | |
;; of the sequence | |
;; Use 'into' to populate a new data structure without an intermediate | |
;; sequence. | |
=> (into [] (map inc) (range 10)) | |
[1 2 3 4 5 6 7 8 9 10] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
;; Examples of 'transducer' composition, note the order of invocation. | |
=> (sequence (comp (filter even?) (map inc)) (range 10)) | |
(1 3 5 7 9) | |
=> (sequence (comp (map inc) (filter even?)) (range 10)) | |
(2 4 6 8 10) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment