diff options
Diffstat (limited to 'src/clojure/contrib')
-rw-r--r-- | src/clojure/contrib/accumulators.clj | 28 | ||||
-rw-r--r-- | src/clojure/contrib/accumulators/examples.clj | 15 |
2 files changed, 42 insertions, 1 deletions
diff --git a/src/clojure/contrib/accumulators.clj b/src/clojure/contrib/accumulators.clj index 9fe140a7..65821976 100644 --- a/src/clojure/contrib/accumulators.clj +++ b/src/clojure/contrib/accumulators.clj @@ -1,7 +1,7 @@ ;; Accumulators ;; by Konrad Hinsen -;; last updated February 12, 2009 +;; last updated February 13, 2009 ;; This module defines various accumulators (list, vector, map, ;; sum, product, counter, and combinations thereof) with a common @@ -179,6 +179,32 @@ "An empty minimum accumulator. Only numbers can be added.") ; +; Numeric range accumulator +; (combination of minimum and maximum) +; +(let [range-tag {::accumulator ::range}] + (defn- make-range + [min max] + (with-meta {:minimum min :maximum max} range-tag))) + +(defvar empty-range (make-range nil nil) + "An empty range accumulator, combining minimum and maximum. + Only numbers can be added.") + +(defmethod combine ::range + [& vs] + (let [total-min (apply min (map :minimum vs)) + total-max (apply max (map :maximum vs))] + (make-range total-min total-max))) + +(defmethod add ::range + [v e] + (let [{min-v :minimum max-v :maximum} v + new-min (if (nil? min-v) e (min min-v e)) + new-max (if (nil? max-v) e (max max-v e))] + (make-range new-min new-max))) + +; ; Counter accumulator ; (defvar empty-counter (with-meta {} {::accumulator ::counter}) diff --git a/src/clojure/contrib/accumulators/examples.clj b/src/clojure/contrib/accumulators/examples.clj index a3d7b026..ee0727e9 100644 --- a/src/clojure/contrib/accumulators/examples.clj +++ b/src/clojure/contrib/accumulators/examples.clj @@ -53,6 +53,21 @@ p2 (add-items empty-product [(/ 1 2)])] (combine p1 p2)) +; Maximum accumulator: combine is max +(let [m1 (add-items empty-maximum [2 3]) + m2 (add-items empty-maximum [(/ 1 2)])] + (combine m1 m2)) + +; Minimum accumulator: combine is min +(let [m1 (add-items empty-minimum [2 3]) + m2 (add-items empty-minimum [(/ 1 2)])] + (combine m1 m2)) + +; Range accumulator: combination of minimum and maximum +(let [m1 (add-items empty-range [2 3]) + m2 (add-items empty-range [(/ 1 2)])] + (combine m1 m2)) + ; String accumulator: combine is concatenation (combine "a" "b" "c" "def") (add "a" (char 44)) |