Erlang模式匹配错误

时间:2014-11-14 14:55:45

标签: erlang pattern-matching

我最近开始学习Erlang,并在尝试匹配时遇到以下错误

以下表达式正常工作:

{A,_,[B|_],{B}}={abc,23,[22,x],{22}}.
Resulting in
A = abc
B = 22

以下表达式不起作用:

{A,_,[_|B],{B}}={abc,23,[22,x],{x}}.
Is resulting in 
** exception error: no match of right hand side value {abc,23,[22,x],{x}}

但是,如果我用[22,x替换'|中的','像下面的工作查找和绑定x到B

{A,_,[_|B],{B}}={abc,23,[22|x],{x}}.
{abc,23,[22|x],{x}}
B.
x

对此的任何解释都将受到高度赞赏。

非常感谢提前

2 个答案:

答案 0 :(得分:1)

您需要仔细研究|运算符的工作原理。它基本上是列表的头部,这是一个元素,并返回列表的尾部,这是其余的。并且喜欢"所有"建议尾巴也是一个清单。它可能是一个元素列表,它甚至可能是空列表,但它仍然是一个列表。

> [Head| Tail] = [23,x].
[23,x]
> Head.
23
> Tail
[x].

因此,在模式匹配中,您指定为尾部[x],而不是仅仅尝试模式匹配x。这就是失败的原因。

旁注:您可以使用|运算符创建新列表,但是您应该谨慎行事。因为您可以创建improper list(并使用[23 | x])。这就是为什么你的"修复"正在努力。

如果您想匹配两个元素列表,可以使用

显式执行
[A, B] =  [23, x].

但如果列表中包含更多或更少的元素,则会失败。

如果您只想在两个第一个元素上匹配,您仍然可以使用|运算符。

> [A, B | Rest] = [23, x].
[23, x]
> A.
23
> B.
x
> Rest.
[].

这只会在单元素或空列表中失败。

答案 1 :(得分:1)

运算符|用于列表的递归定义:[A|B]表示您将元素A添加到现有列表BA是结果列表的第一个元素,称为head,B是名为tail的列表的其余部分。 B也可以分为头部和尾部,并且该过程可以继续,直到尾部等于空列表[]

运算符是列表元素之间的分隔符,因此[A,B]是包含2个元素AB的列表。

可以合并2个运算符:[A,B,C|D]是至少3个元素的列表,ABC以及尾{{1}这可能是空的。

在测试中,您使用了另一种语法:D; 23可以是列表的元素(实际上任何erlang术语都可以是列表的元素)但是x是原子并且不能是列表尾部。这样做打破了列表的递归定义,这种结构不经常使用,被称为不正确的列表。

  • 当您匹配[23|x][_|B]时,您将[_,x]分配给[x],而Bx后面的表达式不匹配

  • 当您与[_|B][_|x]匹配时,您将x分配给B,该x确实与表达式后面的{A,_,[_|B],{B}}={abc,23,[22,x],{[x]}}.匹配,但是正确的方法应该是

  • {{1}}