2013-01-07 10 views
6

Ich versuche, das folgende Beispiel auf die neuen Clojure 1.5 Reduzierungen zu konvertieren Bibliothek:Clojure Minderer Bibliothek - Falten mit max

(reduce max (map inc (range 10))) 
;=> 10 

Wenn ich it- ändern bekomme ich folgende Fehlermeldung:

(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) 

Kann mir jemand eine korrekte Lösung geben?

Antwort

10

Beachten Sie, dass es funktioniert, wenn Sie max mit + ersetzen.

(r/fold + (r/map inc (range 10))) 
; => 55 

Der Unterschied ist die Tatsache, dass unlike +maxdoes not have ein Fall für einen Aufruf ohne Argumente. r/fold erfordert die Kombinationsfunktion - d.h. max -ein Identitätswert anzugeben, wenn ohne Argumente aufgerufen wird. Für * ist es 1, für + ist es 0.

Eine mögliche Lösung wäre, eine max' zu definieren, die als max fungiert, aber wenn sie ohne Argumente aufgerufen wird, gibt sie das negative Unendlich-an identity element für die max-Funktion zurück.

(defn max' 
    ([] Double/NEGATIVE_INFINITY) 
    ([& args] (apply max args))) 
(r/fold max' (r/map inc (range 10))) 
; => 10 

Das gleiche Ergebnis kann mit der r/monoid Funktion erreicht werden.

(r/fold (r/monoid max #(Double/NEGATIVE_INFINITY)) (r/map inc (range 10))) 

Zur weiteren Diskussion siehe Reducers - A Library and Model for Collection Processing, ist Abschnitt Einfachheit Gelegenheit.

+0

Ok - es sieht aus wie sie es in der Google-Gruppe hier diskutiert: https://groups.google.com/forum/?fromgroups=#!searchin/clojure/reduce$20max/clojure/EJ9hOZ8yaos/TULab4pndwoJ – hawkeye

+1

@Jan Dafür gibt es einen Helper namens 'monoid', mit dem Ihr zweites Codebeispiel auf zB reduziert wird '(r/falten (r/monoid max # (Double/NEGATIVE_INFINITY)) (r/map inc (Bereich 10)))' –

+0

@EugeneBeresovksy, danke, ich wusste nicht über die 'Monoid'-Funktion. Ich habe die Antwort aktualisiert. – Jan