【问题标题】:Misunderstanding of the cons operator对 cons 运算符的误解
【发布时间】:2014-12-26 21:52:35
【问题描述】:

这是与 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。如果第三个元素 a 变成了一个列表 [a],那么输出就是:{[a], [b]}。为什么?

【问题讨论】:

    标签: list erlang


    【解决方案1】:

    这是因为在正确的列表中,[... | ...] 运算符的右侧应该是一个列表。左边的元素是附加或提取的头部元素的值,也可以是其他列表,没关系。左侧的最后一个元素指向右侧。这意味着在这种情况下,第一个元素与尾列表匹配

    [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]]]]]]]

    要理解它,你应该这样想,而不是用逗号。 绑定示例: [El1, El2 | Tail] = [a,b,c,d], [El1 | [El2 | Tail]] = [a,b,c,d]. 在这两种情况下El1 = a, El2 = bTail = [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 页面很有用。

    【讨论】:

      【解决方案2】:

      ([[a], [b] , a]) 将匹配第一个子句f2([A1, A2 | A1]) -> {A2, A1};

      所以[A1, A2 | A1] = [[a], [b] , a],你可以得到A1 = [a], A2 = [b],重要的是第二个A1A1 = [a]

      【讨论】:

        【解决方案3】:

        运算符 |用于列表的递归定义:[A|B] 表示将元素 A 添加到现有列表 B。A 是结果列表的第一个元素,称为头,B 是列表的其余部分,称为尾巴。 B也可以拆分为头尾,继续处理直到尾等于空列表[]。

        您的示例可以用不同的方式编写:

        L = [[a], [b] , a]. % element list representation
        L = [[a]|[[b]|[a|[]]]]. % cons list representation
        L = [[a],[b]|[a]]. % mixed representation
        

        在最后一个中,您可以识别 f2/1 函数第一个子句的模式[A1, A2 | A1],因此您得到结果{A2,A1} = {[b],[a]}

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2021-03-30
          • 2017-02-09
          • 1970-01-01
          相关资源
          最近更新 更多