守卫语法中的逗号有什么作用?

What does a comma in the guard syntax do?

在我正在阅读的代码库中,我发现了这样一个函数声明(某些部分丢失):

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 从第一原则编程 中是否提到了这种语法,如果是,在哪里?因为我不记得读过它了。)

守卫在Haskell 2010 section 3.13, Case Expressions中有描述 (该部分是关于 case 表达式,而不是顶级声明,但大概语义是相同的):

<i>guards</i>  →  | <i>guard</i><sub>1</sub>, …, <i>guard</i><sub>n</sub>      (<i>n</i> ≥ 1)
<i>guard</i>   →  <i>pat</i> <- <i>infixexp</i>         (pattern guard)
        |  let <i>decls</i>               (local declaration)
        |  <i>infixexp</i>                (boolean guard)

For each guarded expression, the comma-separated guards are tried sequentially from left to right. If all of them succeed, then the corresponding expression is evaluated in the environment extended with the bindings introduced by the guards. That is, the bindings that are introduced by a guard (either by using a let clause or a pattern guard) are in scope in the following guards and the corresponding expression. If any of the guards fail, then this guarded expression fails and the next guarded expression is tried.

在简单的情况下,逗号的作用类似于布尔值。但是逗号更强大,因为每个守卫都可以引入新的绑定,供后续守卫使用(从左到右)。

卫士中的逗号非常不常见(至少以我的经验而言),我将此功能描述为 Haskell 琐事 - 写作(或者,在大多数情况下,阅读)根本不需要) Haskell。我怀疑 Haskell Programming from first principles 出于这个原因省略了它。

此语法在 Haskell '98 中不合法;这是在 Haskell 2010 年添加到语言规范中的。它是 "pattern guards" 语言扩展的一部分。

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

真正 的用处在于允许您在保护子句内进行模式匹配。语法更改还具有副作用,允许您使用逗号将多个布尔项组合在一起。

(我个人非常不喜欢这个扩展,我对它进入官方规范感到有点震惊,但我们...)