[mercury-users] Beyond "Hello World"

Ralph Becket rafe at cs.mu.OZ.AU
Fri Feb 25 11:23:21 AEDT 2005


Argh.  Hit send by mistake.  Here's my corrected second response.

(I've resent a response to your earlier message.  My replay was, I
think, rejected because of an attachment.)

Martin Proud, Thursday, 24 February 2005:
> I went ahead and added that line and re-compiled factorial.m. I got the  
> same errors as before, I believe, except for the warnings about the  
> first line:
> 
> factorial.m:001: Warning: module should start with a `:- module'  
> declaration.
> factorial.m:001: Syntax error at token 'i': operator or `.' expected.
> factorial.m:  1: Warning: interface for module `factorial' does not  
> export anything.
>                 To be useful, a module should export something.
>                 A file should contain at least one declaration other  
> than
>                 `:- import_module' in its interface section(s).
>                 This would normally be a `:- pred', `:- func', `:-  
> type',
>                 `:- inst' or `:- mode' declaration.
> factorial.m:007: In clause for predicate `factorial.factorial/2':
> factorial.m:007:   error: undefined predicate `=</2'.
> factorial.m:010: In clause for predicate `factorial.factorial/2':
> factorial.m:010:   error: undefined symbol `-/2'.
> factorial.m:012: In clause for predicate `factorial.factorial/2':
> factorial.m:012:   error: undefined symbol `*/2'.
> 
> Here's the code I'm using as a part of factorial.m (maybe I have  
> something wrong here? I'm pretty sure I just copied it from the  
> tutorial?):
> 
> :- import_module int i.

You haven't included the `:- module <modulename>.', `:- interface.' or
`:- implementation.' declarations, all of which should be there.  Also,
there's a spurious `i' at the end of your import_module declaration.

> 
> :- pred factorial(int, int).
> :- mode factorial(in, out) is det.
> 
> factorial(N, F) :-
>     ( N =< 0 ->
>         F = 1
>     ;
>         N1 is N - 1,
>         factorial(N1, F1),
>         F is F1 * N
>     ).

That doesn't look like anything in either tutorial!

What you want to write is something like this in a file fac.m:


:- module fac.

:- interface.

:- import_module int.

:- pred factorial(int, int).
:- mode factorial(in, out) is det.

:- implementation.

factorial(N, F) :-
	( if N =< 0 then
		F = 1
	  else
	  	factorial(N - 1, F0),
	  	F = N * F0
	).


Your use of `is' makes me think you copied the factorial definition from
a Prolog text book.  Mercury is quite happy with functions and
expressions, as you can see from the above.  You can use ( _ -> _ ; _ )
instead of ( if _ then _ else _ ), but it's rather old fashioned.

You can changing the declarations for factorial/2 to


:- func factorial(int) = int.


and the definition to


factorial(N) = ( if N =< 1 then 1 else N * factorial(N - 1) ).


and then use factorial as a function in expressions, which is usually
more convenient than its predicate form.

If you want to add a main loop to your program so you can test factorial
from the command line, add the following to the interface section:


:- import_module io.

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


and this to the implementation section:


main(!IO) :-
	io.read(Result, !IO),
	(
		Result = ok(N),
		io.write_int(factorial(N), !IO),
		io.nl(!IO),
		main(!IO)
	;
		Result = error(_),
		io.write_string("What?\n", !IO)
	;
		Result = eof
	).


(You'll need to type a full stop `.' after each number you type in when
you run this program.)  Note that the !IO syntax may not be recognised
by your version of the Mercury compiler.  As I said in my previous
message, you really should upgrade to the latest ROTD.

Hope this helps,
-- 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