[m-users.] Is there a way to make io functions throw an exception, instead of returning io.res
Peter Wang
novalazy at gmail.com
Sat Mar 30 12:14:07 AEDT 2019
Hi,
On Fri, 29 Mar 2019 11:18:31 -0500, Charles Shuller <charles.shuller at gmail.com> wrote:
> For my current project, I will never attempt to recover from an error, and
> just want to fail reporting the error.
>
> Most io function return an io.res, or something closely related, which
> needs checking instead of throwing an exception. And I get a LOT of
> repetitive, error handling code cluttering up my predicate bodies.
>
> Is there some way I can box those functions up to throw an exception on
> error, instead? Most of my code looks a lot like:
>
> remove_file_recursively(Path, !IO) :-
> io.remove_file_recursively(Path, Res, !IO),
> (
> Res = ok
> ;
> Res = error(Error),
> io.error_message(Error, ErrorString),
> string.format("Could not recursively remove %s: %s", [s(Path),
> s(ErrorString)], ExceptionMessage),
> exception.throw(ExceptionMessage)
> ).
>
> With only minor variations for the position of Res in the io function call,
> and the actual Result type (io.res, io.res(T), io.result, etc.....). So
> it SEEMS like it might be possible to write a predicate like:
> io_det(io.remove_file_recursively,
> Path, !IO)
You could write a higher-order predicate with type and mode:
:- pred throw_on_error(pred(io.res, io, io), io, io).
:- mode throw_on_error(in(pred(out, di, uo) is det), di, uo) is det.
Or, you can simply call a predicate that throws an exception if the
input argument is not ok.
:- pred throw_on_error(io.res::in) is det.
throw_on_error(Res) :-
(
Res = ok
;
Res = error(Error),
throw(Error)
).
Peter
More information about the users
mailing list