5

私はErlangでThinkingという本を読んでいます。「図10:ケースの例」には、次の例があります。

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

それは言う:

9行目が[_One、_Two | _Tail]、前のセクションの最後にあるリストテールのリストマッチングルールを確認します。

しかし、実際に[_One、_Two | _Tail]すべてが期待どおりに機能します。本に誤りがありますか、それとも何か問題がありますか?

4

2 に答える 2

10

エラーではないのではないかと思います。

のセマンティクス

[_One, _Two, _Three | _Tail]

3 つ以上の要素のリストです。

のセマンティクス

[_One, _Two | _Tail]

2 つ以上の要素のリストです。

3 番目のパターン[ _One, _Two ]は既に「2 つの要素のリスト」のケースを示しているため、使用[_One, _Two | _Tail]は少し冗長になります。

「すべてが期待どおりに機能している」には理由があります。4 番目のパターンを 3 番目のパターンの前に配置すると、次のようになります。

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

その後、すべてが期待どおりに機能しません。予想の代わりにMod:many([a,b])得られます。これは、"case" 式が評価されるときに、X がすべてのパターンに対して順番に照合されるためです。そして、この順序は保証されています。が最初に一致するため、が返されます (空のリスト)。manytwomany[a,b][_One, _Two | _Tail]_Tail[]

したがって、[ _One, _Two | _Tail ]あなたのケースでは機能しますが[ _One, _Two , _Three | _Tail ]、後でパターンを切り替える場合に備えて、使用することをお勧めします。

于 2012-06-04T22:00:56.913 に答える
2

本の「間違い」です。以前に 2 つの要素が一致していたことを忘れていたと思います。ただし、一致ルールはできるだけ具体的にする方が保守的にはよいので、「3 つ以上の要素」を一致させたい場合は、それについて具体的に説明し、本のように実行します。将来、誰かが以前のルールを削除したり、何らかの理由でそれらを並べ替えたりする可能性があります。

于 2012-06-04T16:22:19.297 に答える