Подтвердить что ты не робот

Что делает запятая в синтаксисе охраны?

В базе кода, которую я читаю, я нашел объявление функции вроде этого (некоторые части отсутствуют):

filepathNormalise :: BS.ByteString -> BS.ByteString
filepathNormalise xs
    | isWindows, Just (a,xs) <- BS.uncons xs, sep a, Just (b,_) <- BS.uncons xs, sep b
    = '/' `BS.cons` f xs

Что здесь делает запятая?

(Только в качестве бонуса, если кто-то легко это знает: это синтаксис, упомянутый в Haskell Programming, из первых принципов, и если да, где? Как я не помню, чтобы прочитать об этом.)

4b9b3361

Ответ 1

Охранники описаны в Haskell 2010 раздел 3.13, Case Expressions  (в этом разделе речь идет о выражениях case, а не объявлениях верхнего уровня, но предположительно семантика одинакова):

guards  →  | guard1, …, guardn      (n ≥ 1)
guardpat <- infixexp         (pattern guard)
        |  let decls               (local declaration)
        |  infixexp                (boolean guard)

Для каждого защищенного выражения разделители, разделенные запятыми, последовательно проверяются слева направо. Если все они успешны, то соответствующее выражение оценивается в среде, расширенной с привязками, введенными охранниками. То есть привязки, введенные охранником (либо с помощью предложения let, либо с защитой шаблона), находятся в области видимости в следующих защитниках и соответствующем выражении. Если какой-либо из охранников терпит неудачу, то это защищенное выражение терпит неудачу и проверяется следующее охраняемое выражение.

В простом случае запятая выполняет роль, подобную булевой и. Но запятая более мощная в том, что каждый охранник может вводить новые привязки, которые используются последующими охранниками (исходя из слева направо).

Запястья в охранниках довольно необычны (по моему опыту, по крайней мере), что я бы описал эту функцию как мелочь Хаскелла - вовсе не нужно писать (или, по большей части, читать) Haskell. Я подозреваю, что программирование Haskell с первых принципов опустило его по этой причине.

Ответ 2

Этот синтаксис не является законным в Haskell'98; это было добавлено к языковой спецификации в Haskell 2010. Это часть языкового расширения "шаблоны".

https://prime.haskell.org/wiki/PatternGuards

Реальная полезность в этом заключается в том, что вы можете сопоставлять шаблон в предложении guard. Синтаксическое изменение также имеет побочный эффект, позволяющий вам объединить несколько булевых терминов с запятыми.

(Мне лично очень не нравится это расширение, и я немного шокирован, что он попал в официальную спецификацию, но там мы...)