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

时间:2019-07-06 18:07:44

标签: list erlang

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

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

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

3 个答案:

答案 0 :(得分:7)

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

[4, 5, 6 | [7]]

您尝试创建的版本称为不当列表。您可以在Understanding Lists上详细了解它。

答案 1 :(得分:6)

  

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

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

 my_func(tail, [Head|Acc])

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

下面是使用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).

在外壳中:

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

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

4> 

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

4> [1|[2|[3|[4|[5|[]]]]]].
[1,2,3,4,5]

请注意如何将5与空白列表5|[]相对应?这意味着当您到达列表的末尾时,[LastElmt | Tail]LastElmt匹配到5,将Tail匹配到[],这意味着我们可以匹配不同的调用get_evens(Tail, Acc)时的函数子句,例如:

get_evens([], Acc) ->
    lists:reverse(Acc).

答案 2 :(得分:0)

|的使用无关,但与您有关模式匹配的问题有关。 =用于分配,但是由于数据在erlang中是不可变的,因此它也是基本的模式匹配和等效性测试。

Match Operator = in Patterns