2017-05-29 82 views
1

下面基本上是从JA的书抄代码:地图模式匹配,异常错误(绑定)

-module(mapz). 
-export([count_chars/1]). 

count_chars(Str) -> 
    count_chars(Str, #{}). 

count_chars([H|T], #{H := N}=X) -> % line that throws 
    count_chars(T, X#{H := N+1}); 
count_chars([H|T], X) -> 
    count_chars(T, X#{H => 1}); 
count_chars([], X) -> X. 
然而

,在shell编译它给了我

151> c(mapz). 
mapz.erl:7: variable 'H' is unbound 
error 
152> 

我理解在将H用于映射地图中的键之前绑定H的重要性;并且,据我所知,它正在匹配到第一个参数中的列表(字符串)的头部,并因此被第二个参数(与地图匹配)的评估时间所约束。更重要的是,这本书的例子,我怀疑它是正确的。这本书似乎在使用OTP17,然而,我现在已经20岁了,不知道事情是否改变了?但是,哪些东西?

谢谢你的时间。

+1

https://stackoverflow.com/questions/23106543/illegal-pattern-in-map-of-erlang – Dogbert

+0

ha!感谢队友,奇怪为什么SO没有给我提出这个问题/答案。 – alexakarpov

+0

有趣的 - 在那里,他使用“count_characters([H | T],#{H => N} = X) - > ...” - 操作'=>',而本书和我的示例使用' :=”。 – alexakarpov

回答

2
条款 count_chars([H|T], #{H := N}=X) -> ...

编译器不认为H的第一个参数的模式匹配时绑定:[H|T],所以它是无法匹配模式的第二个参数#{H := N}(我认为这可能是可能与实际组装,见my answer to this topic

但有功能你需要在地图库:在Maps erlang doc

即使使用名单较短

count_chars(Str) -> 
    count_chars(Str, #{}). 

count_chars([H|T],X) -> 
    count_chars(T, maps:update_with(H,fun(V) -> V+1 end, 1,X)); 
count_chars([], X) -> 
    X. 

见文档:与foldl/3

count_chars(Str) -> 
    lists:foldl(fun(C,Map) -> maps:update_with(C,fun(Count) -> Count+1 end, 1,Map) end, #{},Str). 
+0

谢谢;我正在考虑这样一个想法:“嗯,我想知道编译器是如何工作的,它能够从第一个参数中'识别'H,并在绑定第二个参数时使用它?”从未在我的生活中编写过编译器,但这不是理所当然的事情,是的。 – alexakarpov

1

不能与钥匙的地图做的模式匹配(至少目前还没有)是一个变量,如:

count_chars([H|T], #{H := N}=X) 

但是这会工作:

count_chars([H|T], #{"MyKey" := N}=X) 

可以更新代码是这样的:

​​
+0

让我想知道乔是如何将书中的例子放在书中,但实际上并不奏效。我想知道他们是否回滚了某个功能或者什么... – alexakarpov