2012-06-04 3 views
4

Я работаю через книгу Thinking in Erlang. В "Рисунок 10: Пример случая" имеет следующий пример:Erlang список совпадений

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

Он говорит:

Если вы задаетесь вопросом, почему линия 9 не матч против [_One, _TWO | _Tail], просмотрите правила соответствия списков для хвостов списка в конце предыдущего раздела.

Но если я действительно против [_One, _Two | _Tail] все работает, как и ожидалось. Есть ли ошибка в книге, или я получаю что-то неправильно?

ответ

7

Я думаю, что это может быть и не ошибка.

Семантика

[_One, _Two, _Three | _Tail] 

список из трех элементов или более.

Семантика

[_One, _Two | _Tail] 

является список из двух элементов или более.

Поскольку третий шаблон [ _One, _Two ] уже указывает случай для «списка из двух элементов», используя [_One, _Two | _Tail], будет немного избыточным.

Существует причина, по которой «все работает должным образом». Если мы поместим четвертый образец перед третьим, который дает:

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

Тогда все будет работать не так, как ожидалось. Mod:many([a,b]) даст many вместо ожидаемого two. Это связано с тем, что когда выражение «case» оценивается, X сопоставляется по очереди со всеми шаблонами. И этот последовательный заказ гарантирован. Возвращается many, так как [a,b] соответствует [_One, _Two | _Tail], а _Tail - [] (пустой список).

Итак, хотя [ _One, _Two | _Tail ] будет работать в вашем случае, используя [ _One, _Two , _Three | _Tail ] считается хорошей практикой в ​​случае, если вы переключите шаблоны впоследствии.

2

Это ошибка в книге. Я думаю, что они забыли, что два элемента подобраны раньше. Тем не менее, полезно поддерживать, насколько это возможно, с помощью соответствующих правил, поэтому, если вы хотите сопоставить «три или более элементов», будьте конкретны и делайте это как в книге. Кто-то может удалить предыдущее правило в будущем или изменить порядок по какой-либо причине.