Skip to content

Allow `let` just before pure/return in ApplicativeDo

Ziyang Liu requested to merge zliu41/ghc:ado into master

The following is currently rejected:

-- 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 LetStmts, there will be one more segment containing only those LetStmts.

Note that if the let statement mentions a name bound previously, then the program is still rejected, for example

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.

Merge request reports