type error = { code : Unix.error ; call : string ; parameter : string } type 'a t = ('a, error) Stdlib.Result.t module Operators = struct let ( let* ) (m : 'a t) (f : 'a -> 'b t) : 'b t = Stdlib.Result.bind m f let ( let+ ) (m : 'a t) (f : 'a -> 'b ) : 'b t = Stdlib.Result.map f m let ( ! ) (value : 'a) : 'a t = Stdlib.Result.Ok value end let return (value : 'a) : 'a t = Stdlib.Result.Ok value let error code call parameter : 'a t = Stdlib.Result.Error { code ; call ; parameter } let log { code ; call ; parameter } = Format.fprintf Format.err_formatter "@[During the call %s(%s), the following error occured:@ - %s@ @]" call parameter (Unix.error_message code) let recover (io : 'a t) ~using ~on : 'a t = match io with | Ok result -> Ok result | Error e -> log e ; if e.code = on then using else Error e let environment_variable (variable : string) : string t = try Ok (Unix.getenv variable) with | Not_found -> error Unix.ENOENT "getenv" variable | Unix.Unix_error (code, call, param) -> error code call param