5 Stimmen

Definition einer eigenen max-Funktion mit variablen Argumenten

Ich lerne Clojure, um die Probleme zu lösen, die auf 4clojure . Eine der Übungen ist die Erstellung eines eigenen max Funktion mit variablen Argumenten.

Ich versuche, dieses einfache Problem mit der REPL zu lösen und bin zu dieser Lösung gekommen:

(defn my-max 
    [first & more] (calc-max first more))

(defn calc-max 
    [m x] 
        (cond (empty? x) m
            (> (first x) m) (calc-max (first x) (rest x))
            :else calc-max m (rest x)))

Das funktioniert gut, aber die Übung erlaubt nicht die Verwendung von def und deshalb muss ich beide Funktionen in einer einzigen zusammenfassen. Wenn ich die calc-max Referenz mit seinem Code ist das Ergebnis:

(defn my-max 
    [first & more] 
    ((fn calc-max 
        [m x] 
            (cond (empty? x) m
                (> (first x) m) (calc-max (first x) (rest x))
                :else calc-max m (rest x)))
                    first more))

Aber dieser Code funktioniert nicht und gibt den nächsten Fehler zurück:

user=> (my-max 12 3 4 5 612 3)
java.lang.ClassCastException: java.lang.Integer cannot be cast to clojure.lang.IFn (NO_SOURCE_FILE:0)

Ich vermute, dieser Fehler kommt von dem Versuch, das Ergebnis der calc-max Funktion und ich vermute, dass es sich um einen Syntaxfehler meinerseits handelt, aber ich kann nicht herausfinden, wie ich ihn beheben kann.

14voto

Justin Thomas Punkte 5399

Hier ist die Funktion, die ich zur Lösung des Problems verwendet habe. Der Punkt ist, max überhaupt nicht zu verwenden.

(fn [& args] (reduce (fn [x y] (if (> x y) x y) ) args ) )

8voto

Alex Ott Punkte 61759

Der eigentliche Fehler ist, dass Sie den Parameter first - es bindet real first Funktion zu nummerieren! Ändern Sie einfach den Namen in einen anderen, und Ihre Variante wird funktionieren. Obwohl es vielleicht besser ist, die Funktion explizit zu benennen, können Sie z.B. anstelle des Aufrufs einer anonymen Funktion Folgendes deklarieren calc-max als lokale Funktion mit letfn zum Beispiel. Also Ihr my-max aussehen wird:

(defn my-max [ff & more]
  (letfn [(calc-max [m x] 
            (cond (empty? x) m
                  (> (first x) m) (calc-max (first x) 
                                            (rest x))
                  :else (calc-max m (rest x))))]
    (calc-max ff more)))

Obwohl ich denke, dass man einfacheren Code schreiben kann:

(defn my-max [& more] (reduce max more))

4voto

4e6 Punkte 10576

Ihre Funktion funktioniert nicht, weil first en fn als Funktion und nicht als Eingabewert behandelt. Wenn Sie also schreiben

user=> (my-max 12 3 4 5 612 3)

es ist talling, die nicht 12 werfen kann, um zu funktionieren. Es kann einfach umgeschrieben werden als

(defn my-max1 [fst & more]
  ((fn calc-max [m x]
     (cond (empty? x) m
           (> (first x) m) (calc-max (first x) (rest x))
           :else (calc-max m (rest x))))
    fst more))

oder sogar ohne fn

(defn my-max [x & xs]
  (cond (empty? xs) x
        (> (first xs) x) (recur (first xs) (rest xs))
        :else (recur x (rest xs))))

0voto

Paul Punkte 7498

Um die Ausnahme, die Sie sehen, ein wenig näher zu erläutern: Wann immer Clojure etwas auslöst wie

java.lang.Integer cannot be cast to clojure.lang.IFn

bei Ihnen bedeutet es, dass versucht wurde, eine Funktion aufzurufen, aber das, was aufgerufen werden sollte, war keine Funktion, sondern etwas anderes. Das passiert normalerweise, wenn Sie Code wie diesen haben

(smbl 1 2 3)

Wenn smbl auf eine Funktion verweist, führt Clojure diese mit den Parametern 1 2 und 3 aus. Aber wenn smbl nicht auf eine Funktion verweist, wird ein Fehler wie der obige angezeigt. Das war mein Hinweis, als ich Ihren Code durchgesehen habe, und wie 4e6 schon sagte, (first x) ist hier der Übeltäter, weil Sie Ihr Funktionsargument first .

0voto

Dennis Ng Punkte 351

Nicht so gut wie die Reduzierung, aber ok:

(fn [& args] (loop [l args, maxno (first args)] (if (leer? l) maxno (if (> maxno (erstes l) ) (recur (rest l) maxno) (recur (rest l) (erste l))))))

Ich nehme an, Sie können cond verwenden.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X