Opened 17 months ago

Last modified 3 weeks ago

#15344 new bug

ApplicativeDo seems to prevent the fail method from being used

Reported by: kccqzy Owned by:
Priority: normal Milestone: 8.10.1
Component: Compiler Version: 8.2.2
Keywords: ApplicativeDo Cc: simonmar
Operating System: Unknown/Multiple Architecture: Unknown/Multiple
Type of failure: None/Unknown Test Case:
Blocked By: Blocking:
Related Tickets: Differential Rev(s):
Wiki Page:

Description

I am not sure if this is intended, but I came across this issue when debugging a runtime exception. It seems like an incomplete pattern match in a do-block with ApplicativeDo enabled will not use the fail method.

If I have a module like this

{-# LANGUAGE ApplicativeDo #-}
{-# OPTIONS_ghc -ddump-simpl #-}
module M where

f :: Maybe (Maybe Int) -> Maybe Int -> Maybe Int
f mgs mid = do
  _ <- mid
  (Just moi) <- mgs
  pure (moi + 42)

main :: IO ()
main = print (f (Just Nothing) (Just 2))

This will result in a runtime exception:

Just *** Exception: repro.hs:(6,13)-(9,17): Non-exhaustive patterns in lambda

But if I remove the ApplicativeDo extension, this code works as normal, producing Nothing as the output.

On a theoretical level I understand why this is happening, but I still find it quite unexpected, especially since the documentation at https://downloads.haskell.org/~ghc/latest/docs/html/users_guide/glasgow_exts.html#things-to-watch-out-for claims that

Your code should just work as before when ApplicativeDo is enabled, provided you use conventional Applicative instances.

If this is not a defect in GHC itself, I'd say it is a defect in documentation in not pointing out this gotcha.

Attachments (1)

repro.hs (251 bytes) - added by kccqzy 17 months ago.

Download all attachments as: .zip

Change History (5)

Changed 17 months ago by kccqzy

Attachment: repro.hs added

comment:1 Changed 17 months ago by simonpj

Cc: simonmar added
Keywords: ApplicativeDo added

comment:2 Changed 16 months ago by bgamari

Milestone: 8.6.18.8.1

These won't be fixed for in GHC 8.6.

comment:3 Changed 11 months ago by osa1

Milestone: 8.8.18.10.1

Bumping milestones of low-priority tickets.

comment:4 Changed 3 weeks ago by Marge Bot <ben+marge-bot@…>

In 6635a3f/ghc:

Fix #15344: use fail when desugaring applicative-do

Applicative-do has a bug where it fails to use the monadic fail method
when desugaring patternmatches which can fail. See #15344.

This patch fixes that problem. It required more rewiring than I had expected.
Applicative-do happens mostly in the renamer; that's where decisions about
scheduling are made. This schedule is then carried through the typechecker and
into the desugarer which performs the actual translation. Fixing this bug
required sending information about the fail method from the renamer, through
the type checker and into the desugarer. Previously, the desugarer didn't
have enough information to actually desugar pattern matches correctly.

As a side effect, we also fix #16628, where GHC wouldn't catch missing
MonadFail instances with -XApplicativeDo.
Note: See TracTickets for help on using tickets.