Higher-order functions can be used to ensure that system resources are disposed, even when a treatment raises an exception. The pattern used by with_output_file
allows a clean separation of concerns: the higher-order with_output_file
functions takes care of managing the system resources bound to file manipulation while the treatment f
only consumes the output channel.
let with_output_file path f =
let c = open_out path in
try
let answer = f c in
(close_out c; answer)
with exn -> (close_out c; raise exn)
Let us use this higher-order function to implement a function writing a string to a file:
let save_string path s =
(with_output_file path) (fun c -> output_string c s)
Using more advanced functions than fun c -> output_string c s
it is possible to save more complex values. See for instance the Marshal module in the standard library or the Yojson library by Martin Jambon.