Другой возможностью было бы сделать то, что делают спецификации соответствия, и использовать атом '_'
вместо необработанного _
.Затем вы могли бы написать функцию, подобную следующей:
member(X, List) when is_tuple(X), is_list(List) ->
member2(X, List).
% non-exported helper functions:
member2(_, []) ->
false;
member2(X, [H|T]) when not is_tuple(H); size(X) =/= size(H) ->
member2(X, T);
member2(X, [H|T]) ->
case is_match(tuple_to_list(X), tuple_to_list(H)) of
true -> true;
false -> member2(X, T)
end.
is_match([], []) ->
true;
is_match(['_'|T1], [_|T2]) ->
is_match(T1, T2);
is_match([H|T1], [H|T2]) ->
is_match(T1, T2);
is_match(_, _) ->
false.
Тогда ваш вызов теперь будет выглядеть так:
member({pos, '_', '_'}, [..., {pos, 1, 2}, ...])
Это не позволит вам сопоставить шаблоны, такие как {A, A, '_'}
(проверка, где первые два элемента идентичны), но если вам не нужны переменные, это должно сработать.
Вы также можете расширить его, чтобы использовать переменные, используя аналогичный синтаксис для соответствия спецификациям ('$1'
, '$2'
и т. Д.) Немного больше работы - добавьте третий параметр в is_match
с привязками переменных, которые вы видели до этого, затем напишите для них предложения функций, аналогичные предложению для '_'
.
Конечно, это не самый быстрый метод.С предупреждением, которое я на самом деле не измерял, я ожидаю, что использование сопоставления с шаблоном в языке с использованием веселья даст гораздо лучшую производительность, хотя и делает сайт вызовов немного более многословным.Это компромисс, который вы должны рассмотреть.