Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Ocaml - parameter type when checking for duplicates in a list

I've got a basic function which checks a list for duplicates and returns true if they are found, false otherwise.

    # let rec check_dup l = match l with
        [] -> false
      | (h::t) ->
        let x = (List.filter h t) in
        if (x == []) then
           check_dup t
        else
           true
    ;;

Yet when I try to use this code I get the error

    Characters 92-93:
          let x = (List.filter h t) in
                                 ^
    Error: This expression has type ('a -> bool) list
           but an expression was expected of type 'a list

I don't really understand why this is happening, where is the a->bool list type coming from?

like image 819
Rowhawn Avatar asked Apr 07 '11 03:04

Rowhawn


People also ask

How to check for duplicates in a list OCaml?

For each element in the input list, add a key-value pair of element, () to the hash table and simultaneously update a list length counter. At the end, check if the list length counter is different from the hash table length (which is O(1)). If they're different, you have duplicate elements in the list.

What does :: mean in OCaml?

If you have two variables called x and xs' then x :: xs' creates a new list with x prepended onto the front of xs' .

How do I truncate a list in OCaml?

Hence, to truncate a list, you need to create a new list that contains only the first elements (this is the only way to get the desired truncated list). let truncate : 'a -> 'a list -> 'a list = fun elt queue -> ...


1 Answers

The type ('a -> bool) list is coming from the type of filter and from the pattern match h::t in combination. You're asking to use a single element of the list, h, as a predicate to be applied to every element of the list t. The ML type system cannot express this situation. filter expects two arguments, one of some type 'a -> bool where 'a is unknown, and a second argument of type 'a list, where 'a is the same unknown type as in the first argument. So h must have type 'a -> bool and t must have type 'a list.

But you have also written h::t, which means that there is another unknown type 'b such that h has type 'b and t has type 'b list. Put this together and you get this set of equations:

'a -> bool == 'b
'a list == 'b list

The type checker looks at this and decides maybe 'a == 'b, yielding the simpler problem

'a -> bool == 'a

and it can't find any solution, so it bleats.

Neither the simpler form nor the original equation has a solution.


You are probably looking for List.filter (fun x -> x = h) t, and you would probably be even better off using List.exists.

like image 190
Norman Ramsey Avatar answered Sep 28 '22 14:09

Norman Ramsey