使用地图时非法模式

时间:2016-07-28 07:48:10

标签: erlang

我的问题与现有的question(和男孩有关,我惊讶地发现它是Erlang本身的一个已知错误!)。我正在使用本书中的count_characters示例,即使我在R19上也会遇到相同的错误。

代码:

% Frequency count of characters in a string
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.

和错误:

1> c(lib_misc).
lib_misc.erl:40: illegal pattern
lib_misc.erl:41: variable 'N' is unbound
error

这里第40行引用count-characters/2的第一个条款。

我的问题是:

  • 我无法理解链接的SO问题究竟是什么错误。有人可以用简单的术语描述哪个变量导致错误,为什么?
  • 这在R19中仍未解决吗?如果不是,它什么时候会?这是可悲的看到作者的书提供了一个例子是如此严重损坏。

我可以看到链接页面上接受的答案使用maps:update之类的内容。我也可以这样做,但我首先想知道错误存在的原因。

1 个答案:

答案 0 :(得分:3)

您看到的当前错误不是来自Erlang错误。 =>用于构建地图,:=用于模式匹配(两者都允许进行更新,不同之处在于:=仅适用于地图中已有的密钥,=>允许添加新密钥)。所以你需要:=模式:

count_characters([H|T], #{ H := N }=X) ->
    % H => N+1 is also legal here, and means the same because we know H is a key of X
    count_characters(T, X#{ H := N+1 }); 

但是,在您修复此问题后,您会遇到问题:H模式中尚未绑定#{ H := N },目前不支持此功能。这可以通过按顺序匹配多个参数模式来修复,以便H[H|T]的约束。这不是在R19B中完成的(至少从这个例子来看),我不知道是否有任何改变这个的计划。我个人认为模式是同时检查的,所以我甚至不确定这种变化是否可取。

你可以通过组合前两个子句并在正文中匹配X而不是头部来解决这个问题:

count_characters([H|T], X) ->
    case X of 
        #{ H := N } -> count_characters(T, X#{ H => N+1 });
        _ -> count_characters(T, X#{ H => 1 })
    end;
count_characters([], X) -> X.