Antwort

4

Das ist eine gute Frage. Um genauer über das Problem zu sein:

Higher-order functions "nehmen oder produzieren andere Funktionen als Argumente oder Ergebnisse". Es gibt also zwei Fälle:

  1. Funktionen, die Funktionen übernehmen. Beispiele: map, reduce, filter. Diese sind nicht zu schwer zu testen; Liefern Sie einfach alle Parameter wie bei einer normalen Funktion.

  2. Funktionen, die Funktionen zurückgeben. Beispiele: (fn [x] (fn [y] (+ x y))), (partial filter #(> % 1)). Diese sind schwer zu testen, da wir die Gleichheit der Funktionen nicht direkt vergleichen können (Suche nach intensionaler und extensionaler Gleichheit für eine gründliche Diskussion).

    Es sollte offensichtlich sein, dass einfach nicht zu testen keine sehr gute Strategie ist. Warum also nicht die Haskell-Ansicht verwenden, dass teilweise angewendete Funktionen im Wesentlichen die gleichen sind wie Funktionen, die Funktionen zurückgeben - mit anderen Worten, übergeben Sie genügend Parameter an die zurückgegebene Funktion, um ein Ergebnis zu erhalten, das Sie auf Gleichheit testen können.

    Achten Sie nur darauf, dass Sie in Ihren Tests einkoppeln - stellen Sie sicher, dass Ihre Testfälle tatsächlich die Spezifikation der Funktion höherer Ordnung testen, nicht nur die Funktion, die zurückgegeben wird.

+0

In diesem Sinne, sind Makros auch speziell die DoXYZ getestet? –

2

Funktionen höherer Ordnung geben immer noch Ergebnisse zurück, so dass Sie sie noch überprüfen können.

Zum Beispiel, wenn Sie map testen wollten, überlegen Sie, was es tun soll: Es soll eine Funktion und eine Sammlung als Argumente erhalten, diese Funktion auf jedes Element in der Sammlung anwenden und eine neue Sammlung von die Ergebnisse.

So eine einfache Art und Weise der Prüfung, die wäre:

(is (= [1 2 3 4] (map inc [0 1 2 3])) 

Das gleiche Prinzip gilt, wenn Sie eine Funktion höherer Ordnung zu testen sind, die das Ergebnis einer anderen Funktion: Sie einfach testen es gibt, was angenommen hat, nach dem Aufruf der Funktion, die es zurückgibt:

(defn adder [n] 
    (fn [x] 
    (+ x n))) 

(is (= ((adder 10) 5) 15)) 

Hoffe, das hilft.

+0

Das macht eigentlich Sinn. Danke, ich denke, ich habe die Funktion nicht als Werte behandelt und etwas anderes gedacht. Solange keine Mutation vorhanden ist, sollte eine Funktion höherer Ordnung, die einen konsistenten Wert für eine Lambda und eine Liste zurückgibt, konsistent mit einer Lambda-Funktion sein, die übergeben wird. Vielen Dank! –

+0

aber was ist mit functiosnn, die schließen zurück? –

+0

Können Sie ein Beispiel geben? Ich verstehe nicht, warum es sich anders verhalten würde. – leonardoborges

Verwandte Themen