这是与 erlang 中的 cons ( | ) 运算符相关的一般问题。我正在复习样本考试,并且存在这个问题:
f2([A1, A2 | A1]) ->
{A2, A1};
f2([A, true | B]) ->
{A, B};
f2([A1, A2 | _]) ->
{A1, A2};
f2([_ | B]) ->
[B];
f2([A]) ->
{A};
f2(_) ->
nothing_matched.
我很困惑为什么以下输入:([[a], [b] , a]) 导致输出:{[b], [a]}
这是为什么?根据我的理解,如果列表中第二个元素(即空列表 [])的拆分与第一个元素相同,则输出将为:A2,A1。如果第 3 个元素 a 成为列表 [a],则输出为:{[a], [b]}。为什么?
最佳答案
这是因为在适当的列表中 [... | ...]
运算符应该是一个列表。左边的元素是 head 元素的附加值或提取值,也可以是其他列表,这无关紧要。左侧的最后一个元素指向右侧。这意味着在这种情况下第一个元素匹配尾列表
[A1, A2 | A1] = [[a], [b], a] = [[a], [b] | [a]] = [[a], [b]]++ [a].
你不能写 [a,b,c | d,e,f,g]
,你只能有一条尾部。但是 [a,b,c | [d,e,f,g]]
将起作用并且等于 [a,b,c,d,e,f,g]
。这意味着您构造具有值 a
的列表元素,它指向值 b
的列表元素,它指向值 c
的列表元素,它指向右侧(无论如何)。
它的等效项(仅使用 |
不带逗号的运算符)是:
[a | [b | [c | [d | [e | [f | [g]]]]]]]
。
要理解它,您应该这样想而不是用逗号。
绑定(bind)示例:
[El1, El2 |尾部] = [a,b,c,d],
[El1 | [El2 |尾部]] = [a,b,c,d]。
在这两种情况下 El1 = a, El2 = b
和 Tail = [c,d] = [c | [d]] = [c | [d | []]]
。
如您所见,[[a],[b], a]
表示值 [a]
的列表元素(这是值 的列表元素a
指向一个空列表 []
) 指向一个值为 [b]
的列表元素,它指向一个值为 a 的列表元素
指向一个空列表 []
。
每个适当列表的最后一个元素都指向空列表 []
所以 [a,b,c] == [a,b,c | 是真的[]].
但是也有不正确的列表,您可以使用非列表作为尾部来构造它们,如 [a,b,c | d]
但这仅在特定情况下有用,并且大多数列表操作不能应用于它们。用法示例之一是 lazy evaluation其中 tail 是一个函数。
我刚刚发现了与您类似的问题,它是 here . 如果还不清楚,你可以找到关于 singly linked list 的 wiki 页面。有用。
关于list - 对 cons 运算符的误解,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27616314/