1
votes

i am trying to write a higher-order function pick, which picks elements that function f outputs as true and then output their values in list.

for example:

#let f a = if a>8 then true else false;;
pick [1;3;4;9;12;22] f;;
- : int list = [9;12;22]

i wrote this code so far but it doesn't work:

let rec pick f list =
    let p1 = f list in
        if (List.hd(p1)==true)
            then List.hd(p1)::pick List.tl(p1)
        else pick  List.tl(p1)

Error: This expression has type 'a list but an expression was expected of type 'b -> bool#

How can i correct it so it will work on lists?

3

3 Answers

3
votes

Here are some of the problems with your code.

  • You are defining pick f list but calling it as pick [list] f. Make sure your argument order is consistent. => This one is the one causing the error message you get.
  • As Nate C-K said. You cannot call f on the whole list but only on elements of the list.
  • Don't use List.hd or List.tl unless you have tested your list for emptiness.
  • Don't use == for structural equality, don't use equality with booleans.
  • if a>8 then true else false should be replaced by just a>8
1
votes

With the expression f list, you are passing the list list to the function f, which isn't what you said you wanted to do. You want to call f on just the head of the list.

Usually in this situation an OCaml programmer will use pattern matching to deconstruct the list, something like this (I haven't tested this code):

let rec pick f list =
  match list with
  | [] -> []
  | h::t -> if f h then h :: pick f t
                   else pick f t
0
votes

The List module already contains the solution, it's the function filter.

let f a = a > 8;;
List.filter f [1;3;4;9;12;22];;
- : int list = [9;12;22]

The function iterates on the list, stocking the elements verifying the given predicate in an accumulator and returns it.

The standard library contains many standard methods such as filter, it is adviced to look at the documentations first as most of your problems can be solved by those functions.

Inria's documentation for the list module:

https://caml.inria.fr/pub/docs/manual-ocaml/libref/List.html