Edit: Disregard this question! See comments below.
I want an OCaml expression which is passed a file (as an “in_channel”), then reads the file line by line, doing some processing, to the end, then returns the result of the processing.
I wrote this test:
let rec sampler_string file string_so_far =
try
let line = input_line file in
let first_two_letters = String.sub line 0 2 in
sampler_string file (string_so_far ^ first_two_letters)
with End_of_file -> string_so_far;;
let a = sampler_string (open_in Sys.argv.(1)) "";;
(Here the “doing some processing” is adding the first two characters of each line to a running tally, and the idea is that at the end a string containing the first two characters of every line should be returned.)
This doesn’t work: OCaml thinks that “sampler_string” produces something of type unit, rather than of type string. (Difficulties then occur later when I try to use the result as a string.) I think this problem is because the only base case happens in an exception (the End_of_file).
So, a specific question and a general question:
- Is there a way to fix this code, by explicitly telling OCaml to expect that the result of sampler_string should be a string?
- Is there some standard, better syntax for a routine which reads a file line by line to the end, and returns the result of line-by-line processing?
As Damien Pollet says, your sampler_string function compiles fine (and runs correctly) on my machine as well, ocaml v3.12.0. However, I’ll answer your questions:
You can specify types on your functions/values using the
:operator. For example, here’s your function with it’s types annotated. You’ll notice that the return type is put at the very end of the function declaration.I do not know if there’s a better way of reading a file, line-by-line. It certainly is a pain to be forced to deal with an end-of-file via exception. Here’s a blog post on the subject, though the function presented there is of reading a file into a list of lines. Another mailing list version.
A couple of nitpicks:
;;to separate function/value definitions, ocamlc can figure it out from whitespace.