I'm making an Air Pollution Monitor system, where you can add various stations, readings, and then read this saved data afterwards.
I have an issue while trying to match various atoms within a single function. My code is:
handleRequest(add_station, {Name, Coordinates}, Monitor) ->
{add_station(Name, Coordinates, Monitor), ok}.
handleRequest(get_station, {Station}, Monitor) ->
{StationData, _} = get_station(Station, Monitor),
{Monitor, StationData}.
But it fails to compile under this error: function handleRequest/3 already defined
I want to call this function like this:
serverLoop(Monitor) ->
receive
{request, Pid, {Action, Payload}} ->
UpdatedMonitorOrError = handleRequest(Action, Payload, Monitor),
if
is_tuple(UpdatedMonitorOrError) ->
% is a tuple like {error, Message} only in case of error occured, is a list otherwise
Pid ! {reply, UpdatedMonitorOrError},
serverLoop(Monitor);
true ->
% UpdatedMonitorOrError is a valid Monitor which could be treated as the next state
Pid ! {reply, Response},
serverLoop(UpdatedMonitorOrError)
end
end.
Where Action
is a certain atom. I want to avoid making multiple receive pattern matching clauses as most of the code would be repeated.
Note that Payload could be a tuple consisted of various number of elements based on the Action atom and this atom should determine the behavior of handleRequest function. Additionally, Response could be a single atom or a data returned from a function.
What I have also tried, to no avail:
handleRequest(add_station, Payload, Monitor) ->
{Name, Coordinates} = Payload,
{add_station(Name, Coordinates, Monitor), ok}.
handleRequest(get_station, Payload, Monitor) ->
{Station} = Payload,
{StationData, _} = get_station(Station, Monitor),
{Monitor, StationData}.
handleRequest(Action, Payload, Monitor) ->
case Action of
add_station ->
{Name, Coordinates} = Payload,
{add_station(Name, Coordinates, Monitor), ok};
get_station ->
{Station} = Payload,
{StationData, _} = get_station(Station, Monitor),
{Monitor, StationData}
end.
In Erlang, clauses of the same function must be separated by a semicolon instead of a dot:
handleRequest(add_station, {Name, Coordinates}, Monitor) ->
{add_station(Name, Coordinates, Monitor), ok};
%% ↑ note ";" instead of "."
handleRequest(get_station, {Station}, Monitor) ->
{StationData, _} = get_station(Station, Monitor),
{Monitor, StationData}.