[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