The code is below:
-module(map_demo).
-export([count_characters/1]).
count_characters(Str) ->
count_characters(Str, #{}).
count_characters([H|T], #{ H => N } = X) ->
count_characters(T, X#{ H := N+1 });
count_characters([H|T], X) ->
count_characters(T, X#{ H => 1});
count_characters([], X) ->
X.
when compiling the code in the Erlang shell, it reported the following errors:
1> c(map_demo).
map_demo.erl:7: illegal pattern
map_demo.erl:8: variable 'N' is unbound
map_demo.erl:10: illegal use of variable 'H' in map
map_demo.erl:7: Warning: variable 'H' is unused
error
I'm new in Erlang, and just can't find anything wrong by myself. How to correct it?
The answers from IRC (#erlang@freenode):
H
is matched 2 times; or once and used to match N then. (This issue also appears with binaries)This should be solved in the coming releases.
As of release 17 this works:
-module(count_chars).
-export([count_characters/1]).
count_characters(Str) ->
count_characters(Str, #{}).
%% maps module functions cannot be used as guards (release 17)
%% or you'll get "illegal guard expression" error
count_characters([H|T], X) ->
case maps:is_key(H,X) of
false -> count_characters(T, maps:put(H,1,X));
true -> Count = maps:get(H,X),
count_characters(T, maps:update(H,Count+1,X))
end;
count_characters([], X) ->
X.
Here is another version (only tested on 18) that is slightly more similar to the one in the book:
-module(count_chars).
-export([count_characters/1]).
count_characters(Str) ->
count_characters(Str, #{}).
count_characters([H|T], X) ->
case maps:is_key(H,X) of
false -> count_characters(T, X#{ H => 1 });
true -> #{ H := Count } = X,
count_characters(T, X#{ H := Count+1 })
end;
count_characters([], X) ->
X.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With