Spec-Zone.ru › Haskell 9

6.2.18. Более свободный синтаксис аргументов функций

BlockArguments
Версия:

8.6.1

Разрешает напрямую использовать выражения do, лямбда-выражения и т. д. в качестве аргумента функции.

В Haskell 2010 выражения некоторых видов можно использовать без скобок в качестве аргумента оператора, но не в качестве аргумента функции. К ним относятся выражения do, лямбда-выражения, if, case и let. Некоторые расширения GHC также определяют языковые конструкции этого типа: mdo (Рекурсивная do-нотация), \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.18.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.

© 2002–2007 The University Court of the University of Glasgow. All rights reserved.
Licensed under the Glasgow Haskell Compiler License.
https://downloads.haskell.org/~ghc/9.14.1/docs/users_guide/exts/block_arguments.html

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API