Erlang は、すべての引数に対して、左から右へ、任意の深さまで、すべての型のインデックスを作成します。私たちが使用する基本的なアルゴリズムは、 Simon Peyton Jones によるThe Implementation of Functional Programming Languages で説明されており、そこから引用したもので、Erlang が型を処理する方法に合うように修正しました。今は少し古いですが、これは私にとって本当の AHA 体験である良い本です。
これは、少なくとも速度のために最適化パターン マッチングを試行するために引数を並べ替える必要がないことを意味します。一貫性があり、明確である方がはるかに優れています。これが私のやり方です。Erlang で関数の引数を順序付ける慣用的な方法はありますか? . これは、次のようなコードに問題がないことを意味します。
foo(X, [{a,A}|Rest], ...) -> ... ;
foo(X, [{b,B}|Rest], ...) -> ... ;
foo(X, [{c,C}|Rest], ...) -> ... ;
foo(X, [{d,D}|Rest], ...) -> ... ;
...
これをネストされた式に分割してコンパイラを「助ける」ことを試みる必要はまったくありませんcase
。通常はさらに悪化します。これを行う唯一の理由は、意図したことを示す際にコードがより明確になるかどうかです。
パターン マッチングの最適化を試みたい場合は、句の順序を変更して、リテラルが発生するすべてのケースがまとめられるようにしてください。例えば:
foo(1, ...) -> ... ;
foo(2, ...) -> ... ;
foo(7, ...) -> ... ;
foo(8, ...) -> ... ;
foo(I, ...) when is_integer(I), I >= 3, I =< 6 ->
... .
よりも良い
foo(1, ...) -> ... ;
foo(2, ...) -> ... ;
foo(I, ...) when is_integer(I), I >= 3, I =< 6 ->
... ;
foo(7, ...) -> ... ;
foo(8, ...) -> ... .
インデックス作成は改善されますが、違いはそれほど大きくないため、無理をしないでください。明確にしておいてください。これは、任意の深さでも有効です。たとえば、リスト内のタプルの最初の要素を持つ最初のコード例です。
これらのほとんどは、関数型言語のかなり標準的なものです。