6.2.18. More liberal syntax for function arguments¶
- BlockArguments¶
- Since:
- 8.6.1 
 - Allow - doexpressions, lambda expressions, etc. to be directly used as a function argument.
In Haskell 2010, certain kinds of expressions can be used without parentheses
as an argument to an operator, but not as an argument to a function.
They include do, lambda, if, case, and let
expressions. Some GHC extensions also define language constructs of this type:
mdo (The recursive do-notation), \case (Lambda-case), and
proc (Arrow notation).
The BlockArguments extension allows these constructs to be directly
used as a function argument. For example:
when (x > 0) do
  print x
  exitFailure
will be parsed as:
when (x > 0) (do
  print x
  exitFailure)
and
withForeignPtr fptr \ptr -> c_memcpy buf ptr size
will be parsed as:
withForeignPtr fptr (\ptr -> c_memcpy buf ptr size)
6.2.18.1. Changes to the grammar¶
The Haskell report defines
the lexp nonterminal thus (* indicates a rule of interest)
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)
      |  …
The BlockArguments extension moves these production rules under
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)              *
      |  …
Now the lexp nonterminal is redundant and can be dropped from the grammar.
Note that this change relies on an existing meta-rule to resolve ambiguities:
The grammar is ambiguous regarding the extent of lambda abstractions, let expressions, and conditionals. The ambiguity is resolved by the meta-rule that each of these constructs extends as far to the right as possible.
For example, f \a -> a b will be parsed as f (\a -> a b), not as f
(\a -> a) b.