[mercury-users] using 'try' for exception handling
Ralph Becket
rafe at cs.mu.OZ.AU
Fri Jun 6 11:10:49 AEST 2003
Goncalo Jorge Coelho e Silva, Thursday, 5 June 2003:
>
>
> Hi,
>
> Fergus' post wasn't too clear for me. I still
> have problems with the predicate, even though I've
> made changes to try it:
>
> Fergus wrote:
>
> >> :- pred tryexcept(io__state, io__state).
> >> :- mode tryexcept(di, uo) is det.
> >> %:- pred tryexcept(string ,io__state, io__state).
> >> %:- mode tryexcept(in, di, uo) is det.
>
> >The commented out version is the one that you need.
>
> >> main(IO1, IO):-
> >> try_io(tryexcept(IO2, IO3), IO1, IO, Result),
> >> %try_io( tryexcept(IO1, IO), Result),
> >> %try_io( tryexcept("string", IO1, IO), Result),
>
> >The syntax that you are looking for here is
>
> > try_io(try_except, Result, IO1, IO)
>
>
>
>
> I get:
> ---------
>
> inter.m:035: In clause for predicate `inter:tryexcept/3':
> inter.m:035: warning: variable `IO_0' occurs only once in this scope.
> inter.m:035: In clause for predicate `inter:tryexcept/3':
> inter.m:035: warning: variable `IO' occurs only once in this scope.
> inter.m:036: In clause for predicate `inter:tryexcept/3':
> inter.m:036: warning: variable `Int3' occurs only once in this scope.
> inter.m:027: In clause for predicate `inter:main/2':
> inter.m:027: in unification of variable `Result'
> inter.m:027: and term `succeeded(IO)':
> inter.m:027: type error in argument(s) of functor `succeeded/1'.
> inter.m:027: Argument 1 (IO) has type `(io:state)',
> inter.m:027: expected type was `string'
>
>
> with this code:
> --------------
>
> :- module inter.
>
> :- interface.
>
> :- import_module io.
>
> :- pred main(io__state, io__state).
> :- mode main(di, uo) is det.
>
> :- pred tryexcept(string, io__state, io__state).
> :- mode tryexcept(in, di, uo) is det.
>
> %:- pred tryexcept(int ,io__state, io__state).
> %:- mode tryexcept(out, di, uo) is det.
>
> :- implementation.
>
> :- import_module string.
> :- import_module exception.
> :- import_module require.
>
>
> main(IO1, IO):-
> try_io(tryexcept, Result, IO1, IO),
> %try_io(tryexcept("string"), Result, IO1, IO),
> (
> Result = succeeded(IO) %,
> %io__write_string("22", IO1, IO)
> ;
> Result = exception(_),
> io__write_string(" string__det_to_int Failed! ", IO1, IO)
> ).
>
>
This
> tryexcept(String, IO_0, IO):-
> string__det_to_int(String) = Int3.
gets the error messages
> inter.m:035: In clause for predicate `inter:tryexcept/3':
> inter.m:035: warning: variable `IO_0' occurs only once in this scope.
> inter.m:035: In clause for predicate `inter:tryexcept/3':
> inter.m:035: warning: variable `IO' occurs only once in this scope.
> inter.m:036: In clause for predicate `inter:tryexcept/3':
> inter.m:036: warning: variable `Int3' occurs only once in this scope.
which mean exactly what they say: each of the variables mentioned
appears only once, which is usually an error.
> what's wrong here?
It's not clear what you're trying to achieve.
Let us assume that you want to call a predicate (I'll use the name
`convert_string_to_int' rather than `tryexcept') that turns a string
argument into an int or throws an expception if the string is not a
valid int representation. Here's the code for convert_string_to_int:
:- pred convert_string_to_int(string, int).
:- mode convert_string_to_int(in, out) is det.
convert_string_to_int(String, Int) :-
Int = string__det_to_int(String).
Next, we want to write out the result of our call. Since
convert_string_to_int/2 doesn't do any IO, I use try/2 rather than
try_io/4.
main(IO0, IO) :-
StringA = "forty two",
try(convert_string_to_int(StringA), ResultA),
print_result(StringA, ResultA, IO0, IO1),
StringB = "42",
try(convert_string_to_int(StringB), ResultB),
print_result(StringB, ResultB, IO1, IO).
Although convert_string_to_int has two parameters, we only give it one
argument because try/2 expects a closure with only one (output)
parameter. You can think of `convert_string_to_int(StringA)' as a
"partial application" of convert_string_to_int/2 which is "completed" by
try/2.
:- pred print_result(string, exception_result(int), io__state, io__state).
:- mode print_result(in, in, di, uo) is det.
print_result(String, failed, IO0, IO) :-
io__format("convert_string_to_int(%s) failed\n",
[s(String)], IO0, IO).
print_result(String, succeeded(Int), IO0, IO) :-
io__format("convert_string_to_int(%s) succeeded returning %d\n",
[s(String), i(Int)], IO0, IO).
print_result(String, exception(Exception), IO0, IO) :-
io__format("convert_string_to_int(%s) threw an exception:\n",
[s(String)], IO0, IO1),
io__print(Exception, IO1, IO2),
io__nl(IO2, IO).
HTH,
- Ralph
--------------------------------------------------------------------------
mercury-users mailing list
post: mercury-users at cs.mu.oz.au
administrative address: owner-mercury-users at cs.mu.oz.au
unsubscribe: Address: mercury-users-request at cs.mu.oz.au Message: unsubscribe
subscribe: Address: mercury-users-request at cs.mu.oz.au Message: subscribe
--------------------------------------------------------------------------
More information about the users
mailing list