Reputation: 183
I'm trying to create a list of unique by appending to a list, but I'm getting this error.
Error: This expression has type 'a list
but an expression was expected of type unit
in_list is a boolean function that checks whether the value is in the list.
if(in_list x seen_list) then print_string("Already found") else seen_list@x in
List.iter uniq check_list;;
It seems like there must be some small syntactic error I need to fix for the append function. Suggestions?
Upvotes: 0
Views: 937
Reputation: 6468
According to your code, you seem to believe that lists are mutable in OCaml, and they are not. Hence seen_list@x
compute a new list but does not change seen_list
.
You could change your code to
let uniq seen_list x =
if in_list x seen_list then
(Printf.printf: "uniq: %d: Already seen.\n" x; seen_list)
else x :: seen_list
in
List.fold_left uniq [] check_list
The uniq
function maps a list of integers to a list of integers without repetitions, logging the entries it skips.
This code is obviously intended to be learning material, I guess, nevertheless you should be aware that it most likely implements a Shlemiel the painter's algorithm.
Upvotes: 1
Reputation: 66818
This is a type error, not a syntactic error.
An OCaml function must always return a result of the same type. Right now, when the item is in the list your function tries to return a different type than if the item is not in the list.
Specifically, when the item is already there your function calls print_string
, which returns ()
. This is called unit
, and is a placeholder representing no interesting value. When the item isn't already there, your function returns a value of type 'a list
. Almost certainly what you need to do is to return a list in all cases.
It's hard to say more without seeing more of your code, but the most usual way to handle this situation is to return the old list when the item is already there and a new, longer list when the item isn't already there.
Update
There are many things to fix in this code, but that's the point of the exercise I assume.
Your next problem seems to be that List.iter
is an imperative function, i.e., it wants to do something rather than produce a result. Hence the function that it iterates over the list should return unit (described above). You're using the function uniq
instead, which returns a list.
If you want to use a higher-order function like List.iter
, which is excellent OCaml style, you will need to use a fold (List.fold_left
or List.fold_right
), whose purpose is to accumulate a result.
Upvotes: 0