-module(count).
-export([count/1]).
count(L) when is_list(L) ->
do_count(L, #{});
count(_) ->
error(badarg).
do_count([], Acc) -> Acc;
do_count([H|T],
The answer is pretty much the same as the one I recently gave here: https://stackoverflow.com/a/46268109/240949.
When you use the same variable multiple times in a pattern, as with H in this case:
do_count([H|T], Acc = #{ H := C }) -> ...
the semantics of pattern matching in Erlang say that this is as if you had written
do_count([H|T], Acc = #{ H1 := C }) when H1 =:= H -> ...
that is, they are first bound separately, then compared for equality. But a key in a map pattern needs to be known - it can't be a variable like H1, hence the error (exactly as for field size specifiers in binary patterns, in the answer I linked to).
The main difference in this question is that you have a function head with two separate arguments, and you might think that the pattern [H|T] should be matched first, binding H before the second pattern is tried, but there is no such ordering guarantee; it's just as if you had used a single argument with a tuple pattern {[H|T], #{ H := C }}.