代码如下:
-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.
在Erlang shell中编译代码时,它报告了以下错误:
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
我是Erlang的新手,我自己也找不到任何错误。如何纠正?
答案 0 :(得分:15)
IRC(#erlang @ freenode)的回答:
H
匹配2次;或曾经和以前用来匹配N. (此问题也出现在二进制文件中)这应该在即将发布的版本中解决。
截至第17版this有效:
-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.
这是另一个版本(仅在18上测试),与书中的版本略有不同:
-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.
答案 1 :(得分:2)
OTP-11616 == erts stdlib hipe dialyzer编译器typer ==
EEP43: New data type - Maps With Maps you may for instance: -- M0 = #{ a => 1, b => 2}, % create associations -- M1 = M0#{ a := 10 }, % update values -- M2 = M1#{ "hi" => "hello"}, % add new associations -- #{ "hi" := V1, a := V2, b := V3} = M2. % match keys with values For information on how to use Maps please see the Reference Manual. The current implementation is without the following features: -- No variable keys -- No single value access -- No map comprehensions Note that Maps is experimental during OTP 17.0.
目前,您可以使用maps
模块来实施count_characters
:
count_characters(Str) ->
count_characters(Str, #{}).
count_characters([H|T], X) ->
count_characters(T, maps:put(H, maps:get(H, X, 0) + 1, X));
count_characters([], X) ->
X.
答案 2 :(得分:1)
如果你想匹配地图,你需要这样:
#{key1 := Pattern1, key2 := Pattern2, ...} = VarContainingAMap.
你可以阅读这篇论文: http://joearms.github.io/2014/02/01/big-changes-to-erlang.html
答案 3 :(得分:1)
@EWit,Felipe Mafra:
地图确实应该做的事情;这里缺少的是减少部分:
count(Str) -> M = count_chars(Str, maps:new()), % maps part, bad naming
L = maps:to_list(M), % to be able to sum
N = [X || {_,X} <- L], % strip the numbers
lists:sum(N). % sum them up
count_chars([H|T], Map) when is_map(Map)->
N = maps:get(H, Map, 0),
count_chars(T, maps:put(H, N + 1, Map));
count_chars([], Map) -> Map.
答案 4 :(得分:-1)
匹配语法中的问题。
匹配使用:=
。实施例
test(#{ key := Test }) ->
Test.
对于相关的键和值使用=>
。例:
M = #{ keynew => 123 }
答案 5 :(得分:-1)
我猜您使用的是R17,因为此功能仅适用于此版本。
看一些文档,我的理解是你应该编写代码(我无法测试它,我仍在使用R15:o)
-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.
答案 6 :(得分:-2)
- 模(count_chars)。
%% API
-export([计数/ 1])。
count(Str) - &gt; count_chars(Str,maps:new())。
当is_map(地图) - &gt; 时,count_chars([H | T],Map)
N = maps:get(H, Map, 0), count_chars(T, maps:put(H, N + 1, Map));
count_chars([],Map) - &gt;地图。