为什么这些列表在Erlang中不等效

Ber*_*ian 2 erlang list

我试图理解|Erlang中的用法,更具体地说为什么此表达式不等效:

[4,5,6|7]=:=[4,5,6,7]

|符号不是仅用于模式匹配,只是为了匹配列表而中断列表吗?

Woj*_*wka 8

|为了创建正确的列表,管道需要在右侧列出。管道在此右侧从左侧附加元素。因此,[4, 5, 6, 7]您需要使用管道进行创建

[4, 5, 6 | [7]]
Run Code Online (Sandbox Code Playgroud)

您尝试的版本会创建所谓的不正确列表。您可以在“ 了解列表”中阅读有关它的更多信息。


7st*_*tud 7

是不是| 符号仅用于模式匹配。

否,cons(构造函数)运算符|既可以用来解构具有模式匹配的列表,又可以用来构造列表。通常,函数的最后一行将是:

 my_func(tail, [Head|Acc])
Run Code Online (Sandbox Code Playgroud)

在那一行,cons运算符为第二个参数创建一个列表。第二个参数是一个列表,它将变量的内容添加HeadAcc列表的前面。

这是一个使用cons运算符来解构列表和构造列表的示例:

-module(a).
-compile(export_all).

get_evens(List) -> 
    get_evens(List, []). %% Add an empty list to the function call to accumulate the results.

get_evens([Head|Tail], Acc) when Head rem 2 == 0 ->  %% deconstruct the first argument into Head and Tail
    get_evens(Tail, [Head|Acc]);  %% construct the second argument for the get_evens() function call
get_evens([_Head|Tail], Acc) ->
    get_evens(Tail, Acc);
get_evens([], Acc) ->
    lists:reverse(Acc).
Run Code Online (Sandbox Code Playgroud)

在外壳中:

2> c(a).
{ok,a}

3> a:get_evens([1, 2, 3, 4, 5]).
[2,4]

4> 
Run Code Online (Sandbox Code Playgroud)

我们之所以可以编写在找到空列表时将结束的递归函数的全部原因是因为可以这样定义一个列表:

4> [1|[2|[3|[4|[5|[]]]]]].
[1,2,3,4,5]
Run Code Online (Sandbox Code Playgroud)

注释如何5 cons'ed与空列表:5|[]?这意味着,当你到一个列表的末尾,[LastElmt | Tail]将匹配LastElmt5Tail[],这意味着当我们调用我们可以匹配不同功能的语句get_evens(Tail, Acc),如:

get_evens([], Acc) ->
    lists:reverse(Acc).
Run Code Online (Sandbox Code Playgroud)