[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