Judking
Judking

Reputation: 6371

Passing map type argument in function in Erlang complains error

Here's my code snippet.

%% test.erl
-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.

%% ErShell
1> c(test).
test.erl:19: illegal use of variable 'H' in map
test.erl:20: illegal use of variable 'H' in map
test.erl:20: variable 'N' is unbound
test.erl:22: illegal use of variable 'H' in map
error

I just don't know why it complains such error, since the following code just worked out fine:

%% test2.erl
birthday(#{age := N} = Person) ->
    Person#{age := N+1}.

%% ErShell
1> c(test2).
2> test2:birthday(#{age => 333}).
#{age => 334}

Thanks in advance.

Upvotes: 1

Views: 456

Answers (2)

VladiC4T
VladiC4T

Reputation: 236

As of today (2021), the feature is still not implemented. However, for larger keys it is recommended to use the update function for reasons of efficiency:

count_characters([H|T], Map) ->
    case N = maps:get(H, Map, 0) of
       0 -> count_chars(T, Map#{H => 1});
       _ -> count_chars(T, Map#{H := N+1}) % update function maps:udpate(...)
    end;

Upvotes: 0

Marc Lambrichs
Marc Lambrichs

Reputation: 2892

The reason is simple: map hasn't been fully implemented yet. Take a look at: http://learnyousomeerlang.com/maps

Also, you might think of alternative implementations, using the stuff that's already possible with maps:

count_characters(Str) -> count_characters(Str, #{}).

count_characters([H|T], Map) ->
    N = maps:get(H, Map, 0),
    count_characters(T, maps:put(H, N + 1, Map));
count_characters([], Map) -> Map.

Upvotes: 4

Related Questions