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



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

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第3.13节,案例表达式 (该节是关于案例表达的,而不是顶级声明,但大概是语义是相同的):

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

对于每个受保护的表达式,从左到右依次尝试了逗号分隔的后卫。如果它们全部成功,则通过守卫引入的绑定在延伸的环境中评估相应的表达式。也就是说,在以下后卫和相应的表达式中,护罩引入的绑定(通过使用LET子句或图案护罩)处于范围。如果任何警卫失败了,则此守卫表达失败,并尝试了下一个保护的表情。

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

守卫中的逗号很少见(至少是我的经验),我将此功能描述为Haskell Trivia - 完全不需要写作(或者在大多数情况下阅读)Haskell。我怀疑 haskell编程是从第一原则省略的。

该语法在Haskell '98中不合法;这已添加到Haskell 2010中的语言规范中。它是"模式防护"语言扩展的一部分。

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

真实有用性在于允许您在"后卫"子句中进行模式匹配。句法变化还具有允许您使用逗号的几个布尔术语的副作用。

(我个人真的不喜欢这个扩展,我有些震惊,它使它成为官方规格,但是我们在...)

相关内容

  • 没有找到相关文章

最新更新