在Erlang中进行模式匹配映射时,为什么未绑定此变量? [英] When pattern matching maps in Erlang, why is this variable unbound?

查看:130
本文介绍了在Erlang中进行模式匹配映射时,为什么未绑定此变量?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

-module(count).
-export([count/1]).

count(L) when is_list(L) ->
  do_count(L, #{});
count(_) ->
  error(badarg).

do_count([], Acc) -> Acc;
do_count([H|T], #{}) -> do_count(T, #{ H => 1 });
do_count([H|T], Acc = #{ H := C }) -> do_count(T, Acc#{ H := C + 1});
do_count([H|T], Acc) -> do_count(T, Acc#{ H => 1 }).

在此示例中,将不会编译映射键"H"存在并且具有与之关联的计数的第三子句.编译器抱怨:

In this example, the third clause where the map key "H" exists and has a count associated with it, will not compile. The compiler complains:

count.erl:11: variable 'H' is unbound    

为什么H不受约束?

这通过以下方式起作用:

This works by the way:

do_count([], Acc) -> Acc;
do_count([H|T], Acc) -> do_count(T, maps:update_with(H, fun(C) -> C + 1 end, 1, Acc)).

但是模式匹配应该似乎可以正常工作,但无效.

But it seems like the pattern match ought to work and it doesn't.

推荐答案

答案与我最近在这里给出的答案几乎相同: https://stackoverflow.com/a/46268109/240949 .

The answer is pretty much the same as the one I recently gave here: https://stackoverflow.com/a/46268109/240949.

当您在模式中多次使用相同的变量时,例如在这种情况下,使用H:

When you use the same variable multiple times in a pattern, as with H in this case:

do_count([H|T], Acc = #{ H := C }) -> ...

Erlang中模式匹配的语义说,就像您写过

the semantics of pattern matching in Erlang say that this is as if you had written

do_count([H|T], Acc = #{ H1 := C }) when H1 =:= H -> ...

也就是说,它们首先被单独绑定,然后进行相等性比较.但是必须知道映射模式中的键-它不能像H1这样的变量,因此会产生错误(与我链接到的答案中的二进制模式中的字段大小说明符一样).

that is, they are first bound separately, then compared for equality. But a key in a map pattern needs to be known - it can't be a variable like H1, hence the error (exactly as for field size specifiers in binary patterns, in the answer I linked to).

此问题的主要区别在于,您有一个带有两个单独参数的函数头,并且您可能认为模式[H | T]应该首先匹配,在尝试第二个模式之前将H绑定,但是存在没有此类订购保证;就像您使用了带有元组模式{[H | T],#{H:= C}}的单个参数一样.

The main difference in this question is that you have a function head with two separate arguments, and you might think that the pattern [H|T] should be matched first, binding H before the second pattern is tried, but there is no such ordering guarantee; it's just as if you had used a single argument with a tuple pattern {[H|T], #{ H := C }}.

这篇关于在Erlang中进行模式匹配映射时,为什么未绑定此变量?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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