使用地图时的非法图案 [英] Illegal pattern when using maps
问题描述
我的问题与现有的问题(和男孩,是我惊讶地发现这是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屋!