Library
Module
Module type
Parameter
Class
Class type
Result value combinators.
Note. OCaml 4.08 provides the Stdlib.Result
module which you should prefer to Rresult
.
Rresult
is a module for handling computation results and errors in an explicit and declarative manner without resorting to exceptions. It defines a result
type equal to OCaml 4.03's result
type and combinators to operate on these values.
Open the module to use it, this defines the result type, the R.Infix
operators R
in your scope.
Consult usage guidelines for the type.
The type for results.
module R : sig ... end
Result value combinators.
These are rough design guidelines, don't forget to think.
Use error messages if:
If the above doesn't hold and your errors need to be processed for localization or error recovery then use a custom error type in your result values.
If your module has specific errors then define an error type, and a result type that tags this error type with the library name (or any other tag that may make sense, see for example exn
) along with the following functions:
module Mod : sig
type error = ...
type 'a result = ('a, [`Mod of error]) Rresult.result
val pp_error : Format.formatter -> [`Mod of error] -> unit
val open_error : 'a result -> ('a, [> `Mod of error]) Rresult.result
val error_to_msg : 'a result -> ('a, Rresult.R.msg) Rresult.result
val f : ... -> 'a result
end
If your library has generic errors that may be useful in other context or shared among modules and to be composed together, then define your error type itself as being a variant and return these values without tagging them.
module Mod : sig
type error = [`Generic of ... | ... ]
type 'a result = ('a, error) Rresult.result
val pp_error : Format.formatter -> error -> unit
val open_error : 'a result -> ('a, [> error]) Rresult.result
val error_to_msg : 'a result -> ('a, Rresult.R.msg) Rresult.result
val f : ... -> 'a result
end
In the latter case it may still be useful to provide a function to tag these errors whenever they reach a certain point of the program. For this the following function could be added to Mod
:
val pack_error : 'a result -> ('a, [> `Mod of error]) Rresult.result
You should then provide the following functions aswell, so that the packed error composes well in the system:
val pp_pack_error : Format.formatter -> [ `Mod of error] -> unit
val open_pack_error : ('a, [ `Mod of error]) Rresult.result ->
('a, [> `Mod of error]) Rresult.result
val error_pack_to_msg : ('a, [ `Mod of error]) Rresult.result ->
('a, Rresult.R.msg) Rresult.result