Erlang地图中的非法模式?

内容来源于 Stack Overflow,并遵循CC BY-SA 3.0许可协议进行翻译与使用

  • 回答 (2)
  • 关注 (0)
  • 查看 (28)

代码如下:

-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的新人,只是自己找不到任何错误。如何纠正?

提问于
用户回答回答于

从版本17开始,可以工作:

-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.
用户回答回答于

引自OTP 17.0发行说明

OTP-11616 == erts stdlib hipe dialyzer编译器类型== 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.

扫码关注云+社区