2012-06-04 2 views
4

나는 Thinking in Erlang이라는 책을 통해 작업하고 있습니다. 에서 "그림 10 : 사건의 예"| 라인 (9) [_One에 대한 일치되지 않는 이유얼랭 목록 일치

당신이 궁금해하는 경우, _TWO :

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

그것은 말한다 다음과 같은 예를 가지고 _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])two 대신에 many을 산출 할 것입니다. 이것은 "case"표현식이 평가 될 때 X가 모든 패턴과 차례로 일치하기 때문입니다. 그리고이 순차 순서가 보장됩니다. [a,b][_One, _Two | _Tail]과 일치하고 _Tail[] (빈 목록)이므로 many이 반환됩니다.

그래도 [ _One, _Two | _Tail ]이 작동한다고해도 [ _One, _Two , _Three | _Tail ]을 사용하면 이후에 패턴을 전환 할 수 있습니다.

2

책에 '오류'가 있습니다. 나는 두 요소가 이전에 매치된다는 것을 잊어 버린 것 같다. 그러나 정합 규칙에 따라 가능한 한 구체적으로 유지 보수하는 것이 좋으므로 "3 개 이상의 요소"와 일치 시키려면 책에 대해 구체적으로 설명하십시오. 누군가는 앞으로 규칙을 제거하거나 어떤 이유로 든 재정렬 할 수 있습니다.