Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Erlang list matching

Tags:

erlang

I'm working through the book Thinking in Erlang. In "Figure 10: Example of case" it has the following example:

many(X) ->
case X of
    [] ->
        none;
    [ _One ] ->
        one;
    [ _One, _Two ] ->
        two;
    [ _One, _Two , _Three | _Tail ] ->
        many
end.

It says :

If you are wondering why line 9 is not a match against [ _One, _Two | _Tail ], review the list matching rules for list tails at the end of the previous section.

But if I actually match against [ _One, _Two | _Tail ] everything still works as expected. Is there an error in the book or am I getting something wrong ?

like image 208
VolkerK Avatar asked Jun 04 '12 16:06

VolkerK


2 Answers

I think it might not be an error.

The semantics of

[_One, _Two, _Three | _Tail]

is a list of three elements or more.

The semantics of

[_One, _Two | _Tail]

is a list of two elements or more.

Since the third pattern [ _One, _Two ] already indicates the case for "a list of two elements", using [_One, _Two | _Tail] would be a little bit redundant.

There is a reason for "everything's working as expected". If we place the fourth pattern before the third one, which gives:

many(X) ->
  case X of
    [] ->
      none;
    [_One] ->
      one;
    [_One, _Two | _Tail] ->  %% Switched
      many;
    [_One, _Two] ->          %% Switched
      two
  end.

Then everything won't work as expected. Mod:many([a,b]) would yield many instead of the expected two. This is because when the "case" expression is evaluated, X is matched in turn against all the patterns. And this sequential order is guaranteed. The many is returned because [a,b] matches [_One, _Two | _Tail] first, with _Tail being [](an empty list).

So, even though [ _One, _Two | _Tail ] would work in your case, using [ _One, _Two , _Three | _Tail ] is considered a good practice in case you would switch the patterns afterwards.

like image 171
Ning Avatar answered Oct 06 '22 19:10

Ning


It's an "error" in the book. I think they forgot that two elements are matched before. It is good for maintenance, however, to be as specific as possible with the matching rules, so if you want to match "three or more elements", be specific about it and do as in the book. Someone may remove the previous rule in the future, or reorder them for whatever reason.

like image 40
Emil Vikström Avatar answered Oct 06 '22 21:10

Emil Vikström