Skip to content

ApplicativeDo return case doesn't handle lets

We ran into this bug in production, this is a simplified reproduction. The following program will not type check, requiring an unnecessary Monad instance:

{-# LANGUAGE ApplicativeDo, GeneralizedNewtypeDeriving #-}

import Data.Functor.Identity
import Data.Monoid

newtype A x = A (Identity x) deriving (Functor, Applicative)

shouldWork :: A ()
shouldWork = do
  a <- pure ()
  b <- pure ()
  let ab = a <> b
  return ab
pepe:~/code/snippets$ ghci ApplicativeDoBug.hs 
GHCi, version 8.0.2: http://www.haskell.org/ghc/  :? for help
[1 of 1] Compiling Main             ( ApplicativeDoBug.hs, interpreted )

ApplicativeDoBug.hs:10:14: error:
    • No instance for (Monad A) arising from a do statement
    • In the expression:
        do { a <- pure ();
             b <- pure ();
             let ab = a <> b;
             return ab }
      In an equation for ‘shouldWork’:
          shouldWork
            = do { a <- pure ();
                   b <- pure ();
                   let ab = ...;
                   return ab }
Failed, modules loaded: none.

There is a simple workaround, which worked for us in production:

workaround :: A ()
workaround = do
  a <- pure ()
  b <- pure ()
  return $
    let ab = a <> b
    in ab

I asked in #ghc and it seems this is not yet fixed in HEAD.

Trac metadata
Trac field Value
Version 8.0.2
Type Bug
TypeOfFailure OtherFailure
Priority normal
Resolution Unresolved
Component Compiler
Test case
Differential revisions
BlockedBy
Related
Blocking
CC
Operating system
Architecture
Edited by Ben Gamari
To upload designs, you'll need to enable LFS and have an admin enable hashed storage. More information