Printing Correct Plurals

From Erlang Community

[edit] Problem

You would like to generate messages reporting quantities with correct grammar. For example, you would like to say "There is 1 monster approaching" or "There are 2 monsters approaching", not "There are 1 monsters approaching."

[edit] Solution

The most portable approach is to make use of Erlangs's generic formatting logic to generate a string based on conditionals:

monster_string(N) ->
    Text = if
              N == 1 -> ["is", 1, ""];
              true   -> ["are", N, "s"]
           end,
    io_lib:format("There ~s ~B monster~s approaching", Text).

1> io:fwrite("~s\n", [cookbook:monster_string(1)]). 
There is 1 monster approaching
ok
2> io:fwrite("~s\n", [cookbook:monster_string(3)]).
There are 3 monsters approaching
ok
> 

An alternative approach would be to define a set of functions to present the correct syntax:

is_are(1) -> "is";
is_are(N) -> "are".

plural(1) -> "";
plural(N) -> "s".

monster_string2(N) ->
  io_lib:format("There ~s ~B monster~s approaching",
      [is_are(N), N, plural(N)]).

3> io:fwrite("~s\n", [cookbook:monster_string2(1)]).
There is 1 monster approaching
ok
4> io:fwrite("~s\n", [cookbook:monster_string2(15)]).
There are 15 monsters approaching
ok
> 

Not much else to say. Perl's Lingua::EN support is far superior to Erlang here. Good idea for a library we could write!

Erlang/OTP Projects
Personal tools