Si noti che funziona quando si sostituisce max
con +
.
(r/fold + (r/map inc (range 10)))
; => 55
La differenza è il fatto che unlike +
max
does not have un caso di una chiamata senza argomenti. r/fold
richiede la funzione di combinazione-i.e. max
- per fornire un valore di identità quando viene chiamato senza argomenti. Per *
è 1
, per +
è 0
.
Una possibile soluzione sarebbe quella di definire un max'
che funge da max
ma quando viene chiamato senza argomenti restituisce l'infinito negativo- an identity element per la funzione max
.
(defn max'
([] Double/NEGATIVE_INFINITY)
([& args] (apply max args)))
(r/fold max' (r/map inc (range 10)))
; => 10
Lo stesso risultato si può ottenere utilizzando la funzione r/monoid
.
(r/fold (r/monoid max #(Double/NEGATIVE_INFINITY)) (r/map inc (range 10)))
Per ulteriori approfondimenti si veda Reducers - A Library and Model for Collection Processing, sezione semplicità è Opportunità.
Ok: sembra che l'abbiano discusso nel gruppo Google qui: https://groups.google.com/forum/?fromgroups=#!searchin/clojure/reduce$20max/clojure/EJ9hOZ8yaos/TULab4pndwoJ – hawkeye
@ Jan C'è un aiuto fn chiamato 'monoid' per questo, usando quello, il tuo secondo esempio di codice si riduce ad es '(r/fold (r/monoid max # (Double/NEGATIVE_INFINITY)) (r/map inc (range 10)))' –
@EugeneBeresovksy, grazie, non sapevo nulla della funzione 'monoid'. Ho aggiornato la risposta. – Jan