2013-09-07 4 views
5

Ich habe heute etwas seltsame Erfahrung mit der F # -Filterfunktion. Der Code ist:F # -Filterfunktion - der Zustand des ersten Arguments scheint umgekehrt zu sein

let rec filter : ('a -> bool) -> 'a list -> 'a list = 
    fun isKept -> function 
     | [] -> [] 
     | (x::xs) -> if isKept x then x::filter isKept xs 
        else filter isKept xs 

let x = filter ((>) 1) [1; -5; -20; 30; -35; 40] 

Dieser Code gibt

val x : int list = [-5; -20; -35] 

Problem ist, wie ich eine Bedingung in dem ersten Argument (> 1) übergeben, erwarte ich es alle Listenelemente des zweiten ausfiltern würde Argument, die größer 1 sind, nicht umgekehrt.

Gibt es etwas offensichtlich klar, dass ich nicht erkennen konnte?

Antwort

6

Ihre Filterfunktion ist in Ordnung. Das Problem ist, dass diese Codezeile:

let x = filter ((>) 1) [1; -5; -20; 30; -35; 40] 

zu diesem Code entspricht, wenn Sie eine explizite Lambda anstelle von teilweise die (>) Betreibern Anwendung:

let x = filter (fun x -> 1 > x) [1; -5; -20; 30; -35; 40] 

Der Grund dafür ist, dass die (>) Die Funktion benötigt zwei Argumente. obwohl das 1 rechts von dem (>) angezeigt wird, wird es nicht als das "richtige" Argument für die Funktion übergeben. Die Lösung ist entweder (<) zu verwenden, anstatt:

> let x = filter ((<) 1) [1; -5; -20; 30; -35; 40];; 

val x : int list = [30; 40] 

oder eine explizite Lambda-Funktion zu verwenden, um sicherzustellen, dass Sie die Argumente in der richtigen Reihenfolge anwenden:

> let x = filter (fun x -> x > 1) [1; -5; -20; 30; -35; 40];; 

val x : int list = [30; 40] 
+0

Schön, dank;) – user2431438

+0

Beachten Sie, dass das Komplement von '(>)' ist nicht '(<)' aber '(<=)'. – Frank

+1

@Frank Sie sind richtig - aber die Frage sagt 'Ich erwarte, dass es alle Listenelemente des zweiten Arguments ausfiltert, die größer [als] 1 sind. So wird '(<)' benötigt, um das richtige Ergebnis zu erhalten. –

Verwandte Themen