BangPatterns出现在哪里?

rem*_*rem 11 haskell ghc strictness

GHC用户指南,好像最Pat可能PBangPat,但也有一些例外.例如,模块中的顶级刘海(例如!main)是不允许的,并且x : !xs无法解析 x : (!xs) parses感谢@chi.关于可以添加刘海的正式规范是什么?我查看了用户指南和报告的一些章节但没有发现任何内容.

Rei*_*ton 6

BangPatterns没有公认的正式规范,因为它们不是任何Haskell报告的一部分.我们对规范最接近的是用户指南以及它链接到的haskell-prime提案.

这两个来源都明确提到模块的顶层不允许爆炸模式.

至于x : !xs,用户指南有关于爆炸模式的语法的说法:

我们在模式的语法中添加了一个新的生产:

pat  ::= !pat
Run Code Online (Sandbox Code Playgroud)

它应与Haskell 2010报告一起阅读:

pat  ::= lpat qconop pat
       | lpat

lpat ::= apat
       | - (integer | float)
       | gcon apat_1 ... apat_k

apat ::= var [ @ apat]
       | ...
       | ( pat )
       | ...
Run Code Online (Sandbox Code Playgroud)

根据这些规则x : !xs实际应该解析(因为!xs是a pat,整个事情是lpat qconop pat).因此,用户指南(和haskell-prime提案)是错误的,或者GHC在这一点上是错误的.

我相信在实践中,GHC接受的语法是"看起来像一个有效表达式的任何东西",包括解释(!x)为运算符的一部分!.例如,(! Just x)被接受为模式,但(! ! x)不是.

  • 实际上[用户指南的相关部分](https://downloads.haskell.org/~ghc/latest/docs/html/users_guide/bang-patterns.html#bang-patterns-sem)是如此之久以至于它链接对于*Haskell 98*报告,当时的BNF语法处理优先级不同.[特别针对模式](https://www.haskell.org/onlinereport/exps.html#sect3.17.1),添加`pat :: =!pat`意味着将其添加到*最低优先级*. (2认同)