A transforming function is a unary function that receives a reducing function and returns a replacement reducing function. The replacement can intercept each reduction step, alter the result, or skip inputs while preserving the reducing contract. section 7.1.2
Its contract has three practical parts:
- Accept the original reducing function as the only argument. section 7.1.2
- Return a two-argument reducing function that receives an accumulator and an input. section 7.1.2
- Use reducer to enhance collection reduction, or folder to enhance reduction within folding; folder does not intercept combinef. section 7.1.2
Filtering through a transforming function
divisible-by-10 wraps the current reducing function and forwards only values divisible by ten. Applying it with r/reducer and into produces [0 10 20 30 40 50 60 70 80 90]. section 7.1.2
(require '[clojure.core.reducers :as r]) ; #1
(defn divisible-by-10 [current-reducing-fn] ; #2
(fn [acc el]
(if (zero? (mod el 10))
(current-reducing-fn acc el)
acc)))
(into [] ; #3
(r/reducer
(range 100)
divisible-by-10))
;; [0 10 20 30 40 50 60 70 80 90]
(r/fold ; #4
(r/monoid merge (constantly {}))
(fn [m k v] (assoc m k (+ 3 v)))
(r/folder
(zipmap (range 100) (range 100))
(fn [rf] (fn [m k v] (if (zero? (mod k 10)) (rf m k v) m)))))
;; {0 3, 70 73, 20 23, 60 63, 50 53, 40 43, 90 93, 30 33, 10 13, 80 83}
Shows the wrapper shape, reducer integration, and fold integration in executable Clojure. section 7.1.2
