简体   繁体   中英

OCaml error filter list using higher order functions

So I have this exercise:

filter (fun x -> x = 0) [(1,0);(2,1);(3,0);(4,1)];;
result int list [1;3]

So basically you have to match your x in fun with the second number in list and if its the same you create new list with the first number.

My solution but is wrong

   let rec filter f = function
   | []->[]
   | x::l -> if f=snd x then fst x :: filter f l else [];;

I get the following error when i want to try the code:

Error: This expression has type int but an expression was expected of type int -> bool

I can't reproduce the problem you report. Here's what I see when I try your code:

$ ocaml
        OCaml version 4.02.1

# let rec filter f = function
   | []->[]
   | x::l -> if f=snd x then fst x :: filter f l else []    ;;
val filter : 'a -> ('b * 'a) list -> 'b list = <fun>
# filter 0 [(1,0); (2,1); (3,0)];;
- : int list = [1]

There are no errors, but it gets the wrong answer. That's what I would expect looking at your code.

The error that you are getting is saying that somewhere the compiler is expecting an int -> bool function, but you are giving it an int . The reason you get this error is because you have an equality ( f = snd x ), where f is of type int -> bool and snd x is of type int . both arguments given to the equality must be of the same type. Instead, what you want to do is simply branch on the result of applying f to the second element of x , such as:

let rec filter f = function
  | []->[]
  | x::l -> if f (snd x) then fst x :: filter f l else [];;

That said, I would recommend using pattern matching instead of fst and snd , such as:

 let rec filter f l = 
     match l with
         | [] -> []
         | (x,y)::l -> if f y then x :: filter f l else filter f l

Note that fy will return something of type bool, which will then determine which branch to take.

Altough Matts answer is right. It's good to just reuse existing functions instead of writing a special from the ground up:

[(1,0);(2,1);(3,0);(4,1)]
|> List.filter (fun (_, x) -> x = 0)
|> List.map fst

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM