Skip to content

GHC doesn't catch missing MonadFail constraint with -XApplicativeDo

-- Bug.hs
module Main where

import Data.Functor.Identity

f :: Identity () -> Identity [Int] -> Identity Int
f i0 i1 = do
  _ <- i0
  [x] <- i1
  pure (x + 42)

main :: IO ()
main = print $ f (Identity ()) (Identity [])

With -XApplicativeDo, GHC compiles this program without error or warning. But the resulting program fails at runtime:

$ ghc-8.8.1 -XApplicativeDo --make Bug.hs
[1 of 1] Compiling Main             ( Bug.hs, Bug.o )
Linking Bug ...
$ ./Bug
Bug: Bug.hs:(6,11)-(9,15): Non-exhaustive patterns in lambda

Only when the -XApplicativeDo option is removed does GHC catch the missing constraint:

$ ghc-8.8.1 --make Bug.hs
[1 of 1] Compiling Main             ( Bug.hs, Bug.o ) [flags changed]

Bug.hs:8:3: error:
    • No instance for (MonadFail Identity)
        arising from a do statement
        with the failable pattern ‘[x]’
    • In a stmt of a 'do' block: [x] <- i1
      In the expression:
        do _ <- i0
           [x] <- i1
           pure (x + 42)
      In an equation for ‘f’:
          f i0 i1
            = do _ <- i0
                 [x] <- i1
                 pure (x + 42)
  |
8 |   [x] <- i1
  |   ^^^^^^^^^

A variation of the problematic program had been reported in #15344 (closed).

To upload designs, you'll need to enable LFS and have an admin enable hashed storage. More information