[m-rev.] diff: Add 99 bottles of beer sample

Julien Fischer jfischer at opturion.com
Fri Nov 20 17:48:36 AEDT 2015


Hi Paul,

On Fri, 20 Nov 2015, Paul Bone wrote:

> Add 99 bottles of beer sample
>
> samples/beer.m
>    Add this sample.
>
>    I found the original version of this sample on 99-bottles-of-beer.net.
>    I've updated it, _tried_ to post a comment to 99-bottles-of-beer.net,
>    added it to rosetta code and thought, being a small example, that it
>    should also belong here.

Oooh, can I play this game too?  If your aim is to provide a more
idiomatic version, I'd suggest:

- not using explicit recursion where the standard library already
   provides a procedure (int.fold_down) that does the same thing.
- use if-then-else rather that (C->T;E)
- there's lots of string appending using ++ going on in your version, I'd
   call append_list instead.

I've attached an alternative  version.

> ---
> samples/beer.m | 61 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
> 1 file changed, 61 insertions(+)
> create mode 100644 samples/beer.m
>
> diff --git a/samples/beer.m b/samples/beer.m
> new file mode 100644
> index 0000000..e0b2d27
> --- /dev/null
> +++ b/samples/beer.m
...

> +:- func beer_stanza(int) = string.
> +
> +beer_stanza(N) = Stanza :-
> +    ( N = 0 ->
> +        Stanza = "Go to the store and buy some more!\n"
> +    ;
> +        NBottles = bottles_line(N),
> +        N1Bottles = bottles_line(N - 1),
> +        Stanza =
> +            NBottles ++ " on the wall.\n" ++

According to the lyrics you're supposed to have a comma there,
not a full stop.

Julien.
-------------- next part --------------
% vim: ts=4 et ft=mercury

:- module beer2.
:- interface.

:- import_module io.

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

:- implementation.

:- import_module int.
:- import_module list.
:- import_module string.

main(!IO) :- int.fold_down(beer, 0, 99, !IO).

:- pred beer(int::in, io::di, io::uo) is det.

beer(N, !IO) :-
    ( if N = 0 then
        io.print_line("Go to the store and buy some more!", !IO)
    else
        bottles(N, " on the wall,\n", !IO),
        bottles(N, ".\nTake one down, pass it around,\n", !IO),
        bottles(N - 1, " on the wall.\n\n", !IO)
    ).

:- pred bottles(int::in, string::in, io::di, io::uo) is det.

bottles(N, T, !IO) :-
    ( if N = 0 then
        io.format("No more bottles of beer%s", [s(T)], !IO)
    else if N = 1 then
        io.format("1 bottle of beer%s", [s(T)], !IO)
    else
        io.format("%d bottles of beer%s", [i(N), s(T)], !IO)
    ).


More information about the reviews mailing list