Гарда

Гарда — выражение, ограничивающее применимость кляузы, используется как дополнение к паттернам, которые не обладают универсальностью. То же: охранное выражение, guard expression.

Наша функция может состоять из целого ряда кляуз, каждая из которых специализируется на своём случае. В следующем примере мы используем гарду when is_number(X) для того, чтобы сфокусировать эту кляузу только на обработку чисел. Другие кляузы, может быть, будут обрабатывать строки, которые тоже, на самом деле числа, но их надо сначала превратить в числа.

some(X) when is_number(X) -> ...

Возможно, нам понадобится кляуза, которая работает только с положительными числами…

some(X) when X > 0 -> ...

Вообще-то этот пример не очень удачен, потому что он сработает не только на числа, но и вообще на абсолютно любой терм. Это связано с особенностями сравнения термов. Если сравнить любой не числовой терм с нулём или любым другим числом, то число окажется меньше. Поэтому для корректности надо переписать так:

some(X) when X > 0, is_number(X) -> ...

Гарда, таким образом, стала состоять из двух выражений, разделённых запятыми. Таких выражений может быть и три, и больше. Каждое из них должно быть true, чтобы в целом гарда тоже была true. Вот такая кляуза никогда не сработает:

some(X) when is_integer(X), is_float(X) -> ...

Число может быть или целым, или вещественным, поэтому в любом случае хотя бы один из этих предикатов вернёт false. А если выражения соединить между собой не точками, а точками с запятой, очень даже может сработать:

some(X) when is_integer(X); is_float(X) -> ...

Если попадётся не число, эта кляуза не сработает. А если число, то сработает — какой-нибудь из этих предикатов окажется истинным. На самом деле, вместо этих двух предикатов лучше написать один is_number(X), но нам тут важно показать, что выражения, разделённые точкой с запятой, в гарде работают как ИЛИ. Если хотя бы одно выражение даст true, гарда целиком тоже будет true.

В гардах не должно возникнуть никаких побочных эффектов. Поэтому в них мы не можем пользоваться своими функциями. И вообще список этих функций сильно ограничен. Вот все бифы, которыми мы можем воспользоваться в гардах:

Документация

Guard Sequences.


© Алексей Карманов, 2024.