【问题标题】:Erlang List Tuple MatchErlang 列表元组匹配
【发布时间】:2014-11-08 22:26:30
【问题描述】:

我正在学习 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}]

在模式匹配之后,预期结果 {a,a,a,b,c} 因为它可以匹配 {{a,a,a},4}

我尝试了 lists:keysearchlists:member,但无法获得预期结果

有什么建议吗?

谢谢

【问题讨论】:

  • {a,a,a,b,c} 如何匹配{{a,a,a},4}?您能解释一下这两者有何相同之处吗?
  • 感谢您的回复。我想匹配 {a,a,a|_} {a,a,a,b,c}。这可能吗?
  • 还是不确定。为什么{a,a,a,b,c} 不匹配{{a,a,a,a,a},10}?元组通常代表某种完整的连接数据;如果您尝试仅使用其中的一部分,也许尝试将其表示为列表?对我来说,如果我真的不明白你想要代表什么,那么很难想出通用算法?也许尝试描述匹配背后的逻辑,从哪里获得输入,以及从哪里使用输出。这可能对我有一点帮助。
  • 不,这不是直接可能的。元组是一个数据块,因此您可以将整个元组相互匹配。所以要匹配{a,b,c},你需要一个像{A,B,C}这样的模式。
  • 现在我已经写了一个答案,我正在考虑编辑问题以改进和概括它,以便其他人可以找到它。匹配似乎是早期学习者的绊脚石,我讨厌这个主题难以调查。有任何异议或建议(任何人)?

标签: list erlang tuples


【解决方案1】:

匹配不是消耗性的。您对匹配工作原理的心智模型将集合操作(​​如集合减法和交集)与比较和赋值混淆了。您的集合操作概念也可能会从一些评论中受益。

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

【讨论】:

  • 感谢您的回答。随时编辑问题。
猜你喜欢
  • 2012-06-08
  • 1970-01-01
  • 2014-04-09
  • 2015-05-06
  • 1970-01-01
  • 2018-04-15
  • 2018-04-07
  • 2019-10-12
  • 1970-01-01
相关资源
最近更新 更多