[mercury-users] list functor style functions

Fergus Henderson fjh at cs.mu.OZ.AU
Fri Nov 12 19:29:57 AEDT 1999


On 12-Nov-1999, Michael Day <mikeday at corplink.com.au> wrote:
> 
> As functions cannot specify different code for different
> modes I'm guessing this will not always be possible, especially
> considering the current standard library has always made the distinction
> between `init' and `is_empty'.

That distinction was made primarily for readability.  In the common
case where you are writing a predicate that only has one mode, I find
it more readable if there is a distinction between those two.

In the (rarer) case where you are writing bidirectional code,
you can alway use `init' and an explicit unification,
or even just call the implied mode of `init'.

> Similarly the code for prepend and remove_head.

I guess you are referring to `list__append' and `list__remove_suffix'?

> Is it desirable to have functions that work in many modes or separate them?
> I would be interested to be able to say:
> 
> 	X = sin(pi)
> 
> and
> 
> 	1.0 = sin(X)
>
> with the appropriate mode settings. I understand with the C interface I
> can possibly do that, but should I *want* to do that?

For that example, probably not.  The reverse mode of `sin' must be `cc_multi'
(or perhaps `multi') since there are an infinite number of solutions
that differ by multiples of 2*pi.

That happens quite often.  Writing bidirectional code is harder
than you might first think.  `io__read' is not the inverse mode
of `io__write'!

However, a solution in many cases is to pass down an extra parameter
indicating the direction.  Code which needs to do different
things for different modes can switch on that parameter.

For an example, see the code below.

Cheers,
	Fergus.

:- module bidirectional.
:- interface.
:- import_module io.

:- pred main(io__state::di, io__state::uo) is det.

:- implementation.
:- import_module string, std_util, list, char.

main -->
	format_list_of_int(read, List),
	format_list_of_int(write, List).

:- type rw --->	read ; write.
:- mode read :: in(bound(read)).
:- mode write :: in(bound(write)).

:- pred format_list_of_int(rw, list(int), io__state, io__state).
:- mode format_list_of_int(write, in, di, uo) is det.
:- mode format_list_of_int(read, out, di, uo) is det.

format_list_of_int(RW, List) -->
	format_int(RW, Val),
	( { Val = no, List = [] }
	; { Val = yes(X), List = [X|_] }
	),
	( { List = [] }
	; { List = [_|_] },
	  format_list_of_int(RW, Xs),
	  { List = [_|Xs] }
	).

:- pred format_int(rw, maybe(int), io__state, io__state).
:- mode format_int(write, in, di, uo) is det.
:- mode format_int(read, out, di, uo) is det.

format_int(read, Val) -->
	my_read_line(MaybeLine),
	{ if	MaybeLine = ok(Chars),
		string__from_char_list(Chars, Line),
		string__to_int(Line, X)
	  then
		Val = yes(X)
	  else
		Val = no
	}.
format_int(write, yes(X)) -->
	io__write_int(X),
	io__write_string("\n").
format_int(write, no) -->
	io__write_string("\n").


:- pred my_read_line(io__result(list(char)), io__state, io__state).
:- mode my_read_line(out, di, uo) is det.

my_read_line(Result) -->
	io__read_line(Result0),
	{
		Result0 = ok(Line0),
		list__reverse(Line0, ['\n'|LineRev])
	->
		list__reverse(LineRev, Line),
		Result = ok(Line)
	;
		Result = Result0
	}.

-- 
Fergus Henderson <fjh at cs.mu.oz.au>  |  "I have always known that the pursuit
WWW: <http://www.cs.mu.oz.au/~fjh>  |  of excellence is a lethal habit"
PGP: finger fjh at 128.250.37.3        |     -- the last words of T. S. Garp.
--------------------------------------------------------------------------
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