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

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

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 из первых принципов, и если да, то где? Как я не помню, читая об этом.)

2 ответа

Решение

Защита описана в разделе 3.13 Haskell 2010, " Выражения падежа" (этот раздел посвящен выражениям падежа, а не объявлениям верхнего уровня, но предположительно семантика одинакова):

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

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

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

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

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

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

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

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

Другие вопросы по тегам