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 ?
I think it might not be an error.
The semantics of
is a list of three elements or more.
The semantics of
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:
Then everything won’t work as expected.
Mod:many([a,b])would yieldmanyinstead of the expectedtwo. This is because when the “case” expression is evaluated, X is matched in turn against all the patterns. And this sequential order is guaranteed. Themanyis returned because[a,b]matches[_One, _Two | _Tail]first, with_Tailbeing[](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.