Erlang case statement

16.8k views Asked by At

I have the following Erlang code and it is giving the warning as follows, when i try to compile it, but that make sense. function need two arguments, but i need to patten match "everything else" rather x, y or z.

-module(crop).
-export([fall_velocity/2]).

fall_velocity(P, D) when D >= 0 ->
case P of
x -> math:sqrt(2 * 9.8 * D);
y -> math:sqrt(2 * 1.6 * D);
z -> math:sqrt(2 * 3.71 * D);
(_)-> io:format("no match:~p~n")
end.

crop.erl:9: Warning: wrong number of arguments in format call. 

I was trying an anonymous variable after io:format, but still it is not happy.

2

There are 2 answers

4
Odobenus Rosmarus On BEST ANSWER

In the format you use ~p. It means -- print value. So you must specify what value to print.

last line of case must be

_ -> io:format("no match ~p~n",[P])

Besides, io:format returms 'ok'. So if P is not x y or z, your function will return 'ok' instead of numeric value. I would suggest to return tagged value to separate correct and error returns. Kind of

fall_velocity(P, D) when D >= 0 ->
case P of
x -> {ok,math:sqrt(2 * 9.8 * D)};
y -> {ok,math:sqrt(2 * 1.6 * D)};
z -> {ok,math:sqrt(2 * 3.71 * D)};
Otherwise-> io:format("no match:~p~n",[Otherwise]),
            {error, "coordinate is not x y or z"}
end.
0
legoscia On

To make the comments to the other answer explicit, this is how I would write that function:

-module(crop).
-export([fall_velocity/2]).

fall_velocity(P, D) when D >= 0 ->
    case P of
        x -> math:sqrt(2 * 9.8 * D);
        y -> math:sqrt(2 * 1.6 * D);
        z -> math:sqrt(2 * 3.71 * D)
    end.

That is, don't handle the incorrect argument in your case expression. If someone passes foo as an argument, you'll get the error {case_clause, foo} along with a stacktrace that points to this function and its caller. This also means that this function cannot leak incorrect values into the rest of the code as a result of being called with incorrect arguments.

Returning {ok, Result} | {error, Error} as in the other answer is equally valid. You'll need to choose the variant that fits your case best.