我正在学习Erlang 假设我有两个列表
[{a,a,a,b,c},{d,d,a,a,b},{a,b,c,d,e}]
[{{a,a,a,a,a},10},{{a,a,a,a},6},{{a,a,a},4}]
Patten Match后的,预期结果{a,a,a,b,c},因为它可以匹配{{a,a,a},4}
我尝试了列表:keysearch 和列表:成员,但无法获得预期的结果
任何建议?
感谢
答案 0 :(得分:3)
匹配不是消耗性的。你的匹配工作的心理模型是比较和赋值的设置操作(如set减法和交集)。您的集合操作概念也可能受益于某些评论。
Erlang的匹配仅 用于赋值和断言(一种比较)。如果我们将未绑定的变量(之前从未使用过)与任何值匹配,则该变量将被绑定(赋值)该值:
Foo = {a,b,c}.
现在Foo
和{a,b,c}
可以互换使用。这是纯粹的符号赋值,就像数学类一样,而不是其他语言意义上的“变量”,其中变量是“值的存储盒”。
如果我们对任何值使用=
运算符并且此绑定符号Foo
,我们正在进行检查比较(断言)而不是赋值。 Foo
在当前上下文中不能表示{a,b,c}
以外的任何内容,因此尝试为其分配任何不同的值会导致异常,但只是声明{a,b,c}
是{a.b.c}
是正确且仍然会产生{a,b,c}
(因为Foo
现在是{a,b,c}
的符号,它可以出现在任何一方,但声明仍然正确。)
否则
{a,b,c} = {a,b,c}.
或
{a,b,c} = Foo.
或
Foo = {a,b,c}.
返回{a,b,c}
,并且不会引发异常,因为我们在此处所做的只是断言 {a,b,c}
确实是{a,b,c}
。
如果我只想分配第一个值,我可以用另一种方式匹配:
{Bar,_,_} = {a,b,c}.
现在Bar
代表a
,_
值被忽略(完全跳过)。原始{a,b,c}
的未更改。如果我们这样做也是如此:
{_,Baz,_} = Foo.
现在Baz
代表b
,Foo
代表{a,b,c}
。这就是它。对于列表,例如[{a,b,c}, {1,2,3}]
,我们仍然可以进行匹配,但由于列表的性质,我们将一次检查一个片段(在解释器中尝试这个):
Spam = [{a,b,c}, {1,2,3}].
[Boo | _] = [{a,b,c}, {1,2,3}].
现在Boo
代表{a,b,c}
,Spam
仍然代表其原始列表。
这就是匹配的全部内容。关于Erlang模式匹配的神奇之处在于它的工作原理,它有多少地方为模式匹配提供了自然的机会,以及如何自然地解决大量需要在其他语言中进行程序检查或直接赋值操作的问题(cond,函数参数,=
,消息接收等。)。
设置和列表操作与Erlang中的模式匹配不同。我建议首先阅读一些基本的学习材料,比如许多优秀的初学者教程和Learn You Some Erlang。