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
[_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.
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With