summaryrefslogtreecommitdiff
path: root/docs/users_guide
diff options
context:
space:
mode:
authorZiyang Liu <unsafeFixIO@gmail.com>2022-04-23 21:31:54 -0700
committerMarge Bot <ben+marge-bot@smart-cactus.org>2022-05-06 19:22:22 -0400
commite2ae9518c0373db7a99058a09388043a66af80ad (patch)
treea14fbe0c8d4703b022b9193275237ea09a81173b /docs/users_guide
parent73b22ff196160036ac10b762bf3a363fa8a451ad (diff)
downloadhaskell-e2ae9518c0373db7a99058a09388043a66af80ad.tar.gz
Allow `let` just before pure/return in ApplicativeDo
The following is currently rejected: ```haskell -- F is an Applicative but not a Monad x :: F (Int, Int) x = do a <- pure 0 let b = 1 pure (a, b) ``` This has bitten me multiple times. This MR contains a simple fix: only allow a "let only" segment to be merged with the next (and not the previous) segment. As a result, when the last one or more statements before pure/return are `LetStmt`s, there will be one more segment containing only those `LetStmt`s. Note that if the `let` statement mentions a name bound previously, then the program is still rejected, for example ```haskell x = do a <- pure 0 let b = a + 1 pure (a, b) ``` or the example in #18559. To support this would require a more complex approach, but this is IME much less common than the previous case.
Diffstat (limited to 'docs/users_guide')
-rw-r--r--docs/users_guide/exts/applicative_do.rst9
1 files changed, 4 insertions, 5 deletions
diff --git a/docs/users_guide/exts/applicative_do.rst b/docs/users_guide/exts/applicative_do.rst
index 460ae3d162..a46d74d957 100644
--- a/docs/users_guide/exts/applicative_do.rst
+++ b/docs/users_guide/exts/applicative_do.rst
@@ -71,9 +71,11 @@ is as follows. If the do-expression has the following form: ::
where none of the variables defined by ``p1...pn`` are mentioned in ``E1...En``,
and ``p1...pn`` are all variables or lazy patterns,
-then the expression will only require ``Applicative``. Otherwise, the expression
+then the expression will only require ``Applicative``. The do expression may also
+contain ``let`` statements anywhere, provided that the right-hand-sides of the ``let``
+bindings do not mention any of ``p1...pn``. Otherwise, the expression
will require ``Monad``. The block may return a pure expression ``E`` depending
-upon the results ``p1...pn`` with either ``return`` or ``pure``.
+upon the results ``p1...pn`` and the ``let`` bindings, with either ``return`` or ``pure``.
Note: the final statement must match one of these patterns exactly:
@@ -187,6 +189,3 @@ terms of ``Monad`` is to use the ``Monad`` operations directly, e.g. ::
instance Applicative MyType where
pure = return
(<*>) = ap
-
-
-