Reputation: 13
I'm learning ocaml so it's maybe trivial.
When I try to build executable of this code:
open Core.Std
let build_counts () =
In_channel.fold_lines stdin ~init:[] ~f:(fun counts line ->
let count =
match List.Assoc.find counts line with
| None -> 0
| Some x -> x
in
List.Assoc.add counts line (count + 1)
)
let () =
build_counts ()
|> List.sort ~cmp:(fun (_,x) (_,y) -> Int.descending x y)
|> (fun l -> List.take l 10)
|> List.iter ~f:(fun (line,count) -> printf "%3d: %s\n" count line)
I get this error:
Error: This pattern matches values of type 'a option but a pattern was expected which matches values of type equal:(Stdio__.Import.string -> Stdio__.Import.string -> bool) -> 'b option
Where is the problem?
Link: https://realworldocaml.org/v1/en/html/files-modules-and-programs.html
Upvotes: 1
Views: 316
Reputation: 2959
Below is the type signature for List.Assoc.find
:
('a, 'b) Base__List.Assoc.t -> equal:('a -> 'a -> bool) -> 'a -> 'b option
The first argument is the associative list (counts
in the example). The last argument (of type 'a
) is the key you're looking for (this is line
in your example). There is another argument, however, of type 'a -> 'a -> bool
which labeled equal
. It's pretty straight-forward that it is a comparison function used by List.Assoc.find
to see whether two keys are equals.
In the case where 'a
is string
, a simple (=)
is enough. You can fix your code by replacing your match
line with the following:
match List.Assoc.find counts ~equal:(=) line with
The List.Assoc.add
function follows the same pattern. You should replace the last line of the build_counts
function with the following:
List.Assoc.add counts ~equal:(=) line (count + 1)
As a side-note, Real World OCaml is getting quite old (this is why some examples are outdated), and the authors are working on a second edition.
Upvotes: 5