От GHC user guide похоже, что большинство Pat
может быть PBangPat
, но есть несколько исключений. например ошибки верхнего уровня в модуле (например, !main
) не разрешены и x : !xs
не удается разобратьx : (!xs) parses
спасибо @chi. Какая формальная спецификация о том, где можно добавить челки? Я просмотрел несколько глав руководства пользователя и отчета, но ничего не нашел.Где может появиться BangPatterns
ответ
Официальной спецификации для BangPatterns нет, поскольку они не являются частью какого-либо отчета Haskell. Самое близкое, что у нас есть к спецификации, - это Руководство пользователя вместе с предложением haskell-prime, к которому он привязан.
Оба этих источника явно указывают, что шаблон банга не разрешен на верхнем уровне модуля.
Что касается x : !xs
, Руководства пользователя имеет это сказать о синтаксисе моделей Bang:
Добавит одного новое производство к синтаксису шаблонов:
pat ::= !pat
It следует рассматривать в сочетании с докладом Haskell 2010:
pat ::= lpat qconop pat | lpat lpat ::= apat | - (integer | float) | gcon apat_1 ... apat_k apat ::= var [ @ apat] | ... | (pat) | ...
Согласно этим правилам x : !xs
фактически должны разбором (с !xs
является 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' означает добавить его с наименьшим приоритетом *. –
Несмотря на тревогу, это чтение '(!! X)' * должно * работать, но это не так. –
@ ØrjanJohansen, о, хорошая точка. Я не пробовал следить за ссылками на отчет, так как я уже опубликовал отчет 2010 на другой вкладке. Это делает описание ближе к реальности, хотя, как вы говорите, все еще не совсем то же самое. –
Хороший вопрос, хотя сомневаюсь, что лучше всего не использовать BangPatterns на всех, кроме старого старого 'seq'. – leftaroundabout
'x: (! Xs)' parses – chi