Date

So you're learning Mercury lang and you have a predicate with multi determinism. Maybe it looks something like this:

:- pred school(string:: in, string:: out) is multi.

school(Fish, ParticularFish) :-
  ( append("One ", Fish, ParticularFish)
  ; append("Two ", Fish, ParticularFish)
  ; append("Red ", Fish, ParticularFish)
  ; append("Blue ", Fish, ParticularFish)
  ).

Which has four solutions for any given string. "One Fish", "Two Fish", "Red Fish", "Blue Fish".

Flash forward. Now you need to deal with I/O, and I/O can't handle multiple solutions because in order to maintain purity Mercury can't backtrack within predicates that do I/O. We need to gather the solutions before returning them to the main predicate.

Luckily there is the solutions/2 predicate which does exactly this. Here's an example:

Fishes = solutions(school("Fish"))

Notice how we omitted the second argument? That's called currying; you can read more here.

main(!IO) :-
  io.read_line_as_string(Result, !IO),
  (
    Result = eof,
    io.format("bye bye...\n", [], !IO)
  ;
    Result = ok(NewlineString),
    String = string.strip(NewlineString),
    Plurals = solutions(school(String)),
    io.format("%s\n", [s(write_list(Plurals))], !IO),
    main(!IO)
  ;
    Result = error(ErrorCode),
    io.format("%s\n", [s(io.error_message(ErrorCode))], !IO)
  ).

If you find any errors, please contact me!