使用地图时的非法图案 [英] Illegal pattern when using maps

查看:127
本文介绍了使用地图时的非法图案的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我的问题与现有的问题(和男孩,是我惊讶地发现这是Erlang本身已知的错误!我正在使用相同的 count_characters 示例,即使我在R19上也会收到相同的错误。

My question is related to an existing question (and boy, was I surprised to see it was a known bug in Erlang itself!). I'm using the same count_characters example from the book, and getting the same error even though I'm on 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 的第一个子句。

Here line 40 refers to the first clause of count-characters/2.

我的问题是:


  • 我无法了解链接的SO问题究竟是什么错误。有人可以简单地描述哪个变量导致错误,为什么?

  • 这是否仍然不固定在R19?如果没有,什么时候会?很遗憾,看到作者的书提供了一个非常糟糕的例子。

我可以看到链接页面上使用的接受的答案像 maps:update 这样的东西。我可以这样做,但是我首先想知道为什么错误存在。

I can see the accepted answer on the linked page uses stuff like maps:update. I could do the same, but I'd first like to know why the error exists.

推荐答案

你看到的当前错误不是来自Erlang的错误。 => 用于构造地图,:= 用于模式匹配(两者都允许更新,区别是:= 仅适用于已经在地图中的键, => 允许添加新的键)。所以在模式中需要:=

The current error you see doesn't come from an Erlang bug. => is used for constructing maps, := for pattern matching (both are allowed for updating, the difference is that := only works for keys already in the map and => allows adding new keys). So you need := in the pattern:

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中完成的(至少从这个例子来看),我不知道有没有计划改变这个。我个人认为,模式是同时检查的,所以我甚至不确定这种变化是否可取。

However, after you fix this you do run into the problem: H isn't bound yet in the #{ H := N } pattern, and this isn't currently supported. This could be fixed by matching multiple argument patterns in order, so that H gets bound by [H|T]. This isn't done in R19B (at least, judging from this example) and I don't know if there are any plans to change this. It makes sense to me personally that the patterns are checked simultaneously, so I am not even sure this change would be desirable.

你可以解决这个问题,结合前两个条款和匹配 X 在体内而不是头:

You can work around this by combining the first two clauses and matching X in the body instead of the head:

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.

这篇关于使用地图时的非法图案的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆