I have a little weird experience with F# filter function today. The code is:
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]
That code returns
val x : int list = [-5; -20; -35]
Problem is, as I pass a condition in the first argument (> 1), I expect it would filter out any list elements of the second argument that are greater 1, not the reverse.
Is there anything obviously clear that I couldn't spot?
Your filter function is fine. The problem is that this line of code:
let x = filter ((>) 1) [1; -5; -20; 30; -35; 40]
Is equivalent to this code if you use an explicit lambda instead of partially applying the (>)
operator:
let x = filter (fun x -> 1 > x) [1; -5; -20; 30; -35; 40]
The reason for this is that the (>)
function takes two arguments; even though the 1
appears to the right of the (>)
, it's not passed as the "right" argument to the function. The solution is to either use (<)
instead:
> let x = filter ((<) 1) [1; -5; -20; 30; -35; 40];;
val x : int list = [30; 40]
or to use an explicit lambda function to ensure you apply the arguments in the correct order:
> let x = filter (fun x -> x > 1) [1; -5; -20; 30; -35; 40];;
val x : int list = [30; 40]
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With