I'm trying to convert the following example to the new Clojure 1.5 reducers library:
(reduce max (map inc (range 10)))
;=> 10
When I change it- I get the following error:
(r/fold max (r/map inc (range 10)))
;ArityException Wrong number of args (0) passed to: core$max clojure.lang.AFn.throwArity (AFn.java:437)
Can someone give me a correct solution?
Notice that it works when you substitute max
with +
.
(r/fold + (r/map inc (range 10)))
; => 55
The difference is the fact that unlike +
max
does not have a case for an invocation with no arguments. r/fold
requires the combining function—i.e. max
—to provide an identity value when called without arguments. For *
it's 1
, for +
it's 0
.
A potential solution would be to define a max'
which acts as max
but when called with no arguments it returns the negative infinity—an identity element for the max
function.
(defn max'
([] Double/NEGATIVE_INFINITY)
([& args] (apply max args)))
(r/fold max' (r/map inc (range 10)))
; => 10
The same result can be achieved using the r/monoid
function.
(r/fold (r/monoid max #(Double/NEGATIVE_INFINITY)) (r/map inc (range 10)))
For further discussion see Reducers - A Library and Model for Collection Processing, section Simplicity is Opportunity.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With