# [mercury-users] Absolute beginner's problem

Ralph Becket rafe at cs.mu.OZ.AU
Fri Apr 23 10:55:04 AEST 2004

```Maurizio Colucci, Thursday, 22 April 2004:
> Hello again,
>
> Am I forced to use the if-then-else notation? The compiler cannot figure out
> this...
>
> :-pred test(float, string).
> :-mode test(in, out) is det.
> test(F, S):-
> 	F = 0.0,
> 	S = "hi".
> test(F, S):-
> 	F \= 0.0,
> 	S = "there".

[Be aware that `X \= Y' is syntactic sugar for `not (X = Y)'.]

The compiler understands that switches on different data constructors
are exclusive, but it doesn't understand (yet) that two goals can be
both mutually exclusive and exhaustive.

We did have a summer student working on adding this facility to the
language, but unfortunately the work wasn't completed.

So, yes, in this case you have to use an if-then-else:

test(F, S) :-
( if   F = 0.0
then S = "hi"
else S = "there"
).

On the other hand, you don't have to use if-then-elses for switches,
such as

:- type is_zero ---> zero ; non_zero.

:- pred test(is_zero::in, string::out) is det.

test(zero,     "hi").
test(non_zero, "there").

(1) If a predicate has only one mode then we've found that the single
"predmode" declaration (as I used above) is easier to read, especially
as the number of arguments grows.

(2) If a predicate has a single `(in, in, ..., in, out) is det' mode
then it's usually much more convenient to write it as a function,
because for this particular case Mercury allows you to omit the mode
information:

:- func test(is_zero) = string.

test(zero)     = "hi".
test(non_zero) = "there".

-- Ralph
--------------------------------------------------------------------------
mercury-users mailing list
post:  mercury-users at cs.mu.oz.au