There are some text files which needed to be manipulated line by line. I wrote a withFile function as below:
let withFile fn handle =
let rec iter_lines fh =
try
handle (input_line fh);
iter_lines fh
with _ -> close_in fh in
iter_lines (open_in fn);;
So i can manipulate each file as :
withFile "file1.txt" (fun line -> (*...*))
withFile "file2.txt" (fun line -> (*...*))
...
But I am not sure how to exit elegantly when i do not want to handle all lines. For example:
withFile "file3.txt" (fun line ->
(*when the line meets some condition, i will exit without handling other lines*)
);
Any suggestion is appreciated !
Your function
iter_linesisn’t tail recursive, which means you will probably exhaust your stack space if you process a very large file this way. The reason it isn’t tail recursive is that it has to establish and tear down thetry ... withmechanism for catching exceptions.Other than that, this looks really good to me. This kind of higher-order function is what OCaml (and FP) is all about.
One way to make it tail recursive is to move the exception handling out to the containing function. I would also be more specific about the exception that you want to handle. So you get this:
If you want to be able to exit early, one easy way is to have your handle function return a boolean that tells whether to continue processing lines or not. You would end up with something like this:
If you want to be able to use an exception to exit early, you’d need to catch all exceptions in
withFile, close the file, then re-raise any exception other thanEnd_of_file. This gives you code that looks like this: