# [mercury-users] Can this be done better?

Michael Richter ttmrichter at gmail.com
Mon Jan 30 22:55:18 AEDT 2012

```*Issue #1*

I've decided to get serious learning Mercury and I'm doing so by filling in
snippets at Rosetta Code <http://rosettacode.org>.  Today's
exercise<http://rosettacode.org/wiki/First-class_functions#Mercury>has
me a bit flummoxed.  While it works, at issue is an ugly third clause
on the predicate providing the desired functionality.  Here's the code:

:- module firstclass.

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

:- implementation.
:- import_module exception, list, math, std_util.

main(!IO) :-
Forward = [math.sin, math.cos, (func(X) = math.ln(X))],
Reverse = [math.asin, math.acos, (func(X) = math.exp(X))],
apply(list.zip(Forward, Reverse), [], Results),
io.write_list(Results, ", ", io.write_float, !IO),
io.write_string("\n", !IO).

:- pred apply(list((func(float) = float)), list(float), list(float)).
:- mode apply(in, in, out) is det.
apply([], A, Results) :- Results = A.
apply([F, R|Functions], A, Results) :-
apply(Functions, [compose(R, F, 0.5) | A], Results).
apply([_], _, _) :- throw("This can't happen!").

The problem is that apply/3 without that third clause is deemed semidet
because the second clause's head "can fail" (in that R may not always be
bound according to the compiler).  Of course this is nonsense in this given
situation because the list being passed in will *always* come in pairs, but
naturally the compiler can't know that.  For me to get this code to compile
I have to add that third clause (which will never be evaluated) just
because.

Now this bugs me because I know that Mercury can do better.  Indeed I
suspect I'm missing something in the mode declaration that could tell the
compiler that apply's first argument *must* have an even number of entries
but I just can't figure out how to say it.

So how would I go about getting rid of that third clause?

*Issue #2*

In looking through the Library Reference, I keep seeing the :-
promisestatement used.  For example:

:- promise all [A, B, C, ABC]
(
( some [AB] (list.append(A, B, AB), list.append(AB, C, ABC)) )
<=>
( some [BC] (list.append(B, C, BC), list.append(A, BC, ABC)) )
).

The language reference only mentions this (and other declarations) in
passing<http://www.mercury.csse.unimelb.edu.au/information/doc-release/mercury_ref/Declarations.html#Declarations>,
however, and then never talks about them again.  Specifically section 2.6
says that :- promise should be documented in the Modules
section<http://www.mercury.csse.unimelb.edu.au/information/doc-release/mercury_ref/Modules.html#Modules>,
but I can't find that there.

So how do I decode such :- promise declarations, and where, if anywhere,
are they documented?

--
"Perhaps people don't believe this, but throughout all of the discussions
of entering China our focus has really been what's best for the Chinese
people. It's not been about our revenue or profit or whatnot."
--Sergey Brin, demonstrating the emptiness of the "don't be evil" mantra.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.mercurylang.org/archives/users/attachments/20120130/d97b0778/attachment.html>
```