Bercovici Adrian
Bercovici Adrian

Reputation: 9360

Why are these lists not equivalent in Erlang?

I am trying to understand the usage of | in Erlang ,more specifically why is this expression not equivalent:

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

Isn't the | symbol used just for pattern matching , just to break the list in order to match it ?

Upvotes: 3

Views: 383

Answers (3)

Samwar
Samwar

Reputation: 143

Not related to the use of the |, but related to your question about pattern matching. The = is used for assignment, but because data is immutable in erlang, it is also a basic pattern match and test for equivalency.

Match Operator = in Patterns

Upvotes: 0

7stud
7stud

Reputation: 48599

Isn't the | symbol used just for pattern matching.

No, the cons (constructor) operator, |, can be used to both deconstruct a list with pattern matching and construct a list. Often, the last line of a function will be:

 my_func(tail, [Head|Acc])

In that line, the cons operator creates a list for the second argument. The second argument is a list which adds the contents of the variable Head to the front of the Acc list.

Here is an example using the cons operator to both deconstruct a list and construct a list:

-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).

In the shell:

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

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

4> 

The whole reason we can write recursive functions that will end when the empty list is found is because a list can be defined like this:

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

Note how 5 is cons'ed with the empty list: 5|[]? That means when you get to the end of a list,[LastElmt | Tail] will match LastElmt to 5 and Tail to [], which means we can match a different function clause when we call get_evens(Tail, Acc), e.g.:

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

Upvotes: 7

Wojtek Surowka
Wojtek Surowka

Reputation: 20993

The pipe | in order to create a proper list needs a list on the right side. To this right side the pipe appends elements from the left side. So to create [4, 5, 6, 7] with the pipe you need

[4, 5, 6 | [7]]

The version you tried creates so called improper list. You can read more about it at Understanding Lists.

Upvotes: 10

Related Questions