:- module salut.
:- interface.
:- import_module io, list.
:- typeclass greetable(T) where [
func the(T) = string,
func name(T) = string
].
:- type traffic(T)
---> arriving(T)
; leaving(T)
; nothing(int).
:- pred announce(list(traffic(T))::in, io::di, io::uo) is det <= (greetable(T)).
:- pred hello(traffic(T), io, io) <= (greetable(T)).
:- mode hello(in, di, uo) is det.
:- implementation.
:- import_module string.
announce(Events, !IO) :- foldl(announcement, Events, !IO).
hello(nothing(_), !IO).
hello(arriving(Who), !IO) :-
io.format("Hello, %s.\n", [s(name(Who))], !IO).
hello(leaving(Who), !IO) :-
io.format("See you again, %s.\n", [s(name(Who))], !IO).
:- pred announcement(traffic(T)::in, io::di, io::uo) is det <= (greetable(T)).
announcement(nothing(N), !IO) :-
sleep(N, !IO).
announcement(arriving(W), !IO) :-
io.format("Now arriving: %s %s!\n", [s(the(W)), s(name(W))], !IO).
announcement(leaving(W), !IO) :-
io.format("%s %s has left the party.\n", [s(the(W)), s(name(W))], !IO).
:- pred sleep(int::in, io::di, io::uo) is det.
:- pragma foreign_decl("C", "#include <unistd.h>").
:- pragma foreign_proc("C",
sleep(N::in, _IO0::di, _IO::uo),
[will_not_call_mercury, promise_pure],
"
sleep(N);
").