-
BlockArguments -
- Since:
-
8.6.1
Разрешает
doвыражения, лямбда-выражения и т.д. использовать непосредственно в качестве аргумента функции.
В Haskell 2010 определённые виды выражений могут использоваться без скобок в качестве аргумента оператора, но не в качестве аргумента функции. К ним относятся do, лямбда-, if, case, и let выражения. Некоторые расширения GHC также определяют конструкции языка такого типа: mdo (Рекурсивный do-notation), \case (Лямбда-case) и proc (Стрелочная нотация).
Расширение BlockArguments позволяет использовать эти конструкции непосредственно в качестве аргумента функции. Например:
when (x > 0) do print x exitFailure
будет разбор как:
when (x > 0) (do print x exitFailure)
и
withForeignPtr fptr \ptr -> c_memcpy buf ptr size
будет разбор как:
withForeignPtr fptr (\ptr -> c_memcpy buf ptr size)
6.2.17.1. Изменения в грамматике
Отчёт Haskell определяет lexp нетерминал следующим образом (* указывает правило, которое нас интересует):
lexp → \ apat1 … apatn -> exp (lambda abstraction, n ≥ 1) *
| let decls in exp (let expression) *
| if exp [;] then exp [;] else exp (conditional) *
| case exp of { alts } (case expression) *
| do { stmts } (do expression) *
| fexp
fexp → [fexp] aexp (function application)
aexp → qvar (variable)
| gcon (general constructor)
| literal
| ( exp ) (parenthesized expression)
| qcon { fbind1 … fbindn } (labeled construction)
| aexp { fbind1 … fbindn } (labelled update)
| …
Расширение BlockArguments перемещает эти правила вывода под aexp
lexp → fexp
fexp → [fexp] aexp (function application)
aexp → qvar (variable)
| gcon (general constructor)
| literal
| ( exp ) (parenthesized expression)
| qcon { fbind1 … fbindn } (labeled construction)
| aexp { fbind1 … fbindn } (labelled update)
| \ apat1 … apatn -> exp (lambda abstraction, n ≥ 1) *
| let decls in exp (let expression) *
| if exp [;] then exp [;] else exp (conditional) *
| case exp of { alts } (case expression) *
| do { stmts } (do expression) *
| …
Теперь lexp нетерминал избыточен и может быть удалён из грамматики.
Обратите внимание, что это изменение опирается на существующее метаправило для разрешения неоднозначностей:
Грамматика неоднозначна в отношении объёма лямбда-абстракций, выражений let и условных выражений. Неоднозначность разрешается метаправилом, которое предполагает, что каждая из этих конструкций распространяется как можно дальше вправо.
Например, f \a -> a b будет разбор как f (\a -> a b), а не как f
(\a -> a) b.