Erlang индексы по всем аргументам слева направо, на любую глубину и для всех типов.Базовый алгоритм, который мы используем, описан и взят из Реализация функциональных языков программирования Саймоном Пейтоном Джонсом, и я изменил его, чтобы он соответствовал тому, как Эрланг обрабатывает типы.Это хорошая книга, даже если она немного устарела, для меня это реальный опыт AHA.
Это означает, что нет реальной необходимости переупорядочивать аргументы, чтобы попытаться оптимизировать сопоставление с образцом, по крайней мере, не для скорости,Намного лучше быть последовательным и ясным, вот как I делает это, Есть ли идиоматический способ упорядочить аргументы функции в 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, ...) -> ... .
Индексирование будет лучше, но, опять же, не переусердствуйте, поскольку разница не так уж велика, держите ее в чистоте.Это также справедливо для любой глубины, например, в первом примере кода с первым элементом кортежа в списке.
Большинство из них довольно стандартны для функциональных языков.