
#11982: Typechecking fails for parallel monad comprehensions with polymorphic let (GHC 7.10.3 through 8.6.3) -------------------------------------+------------------------------------- Reporter: simonpj | Owner: josefs Type: bug | Status: new Priority: normal | Milestone: Component: Compiler | Version: 7.10.3 Resolution: | Keywords: ApplicativeDo Operating System: Unknown/Multiple | Architecture: Type of failure: GHC rejects | Unknown/Multiple valid program | Test Case: Blocked By: | Blocking: Related Tickets: | Differential Rev(s): Wiki Page: | -------------------------------------+------------------------------------- Comment (by josef): @goldfile can you elaborate on what you mean by incorrect impredicativity? I don't have a concrete plan yet, but it seems to me that, at least in the case of ApplicativeDo, this is mostly a matter of making sure that the algorithm which groups statements doesn't place the LetStmts in unfortunate positions. In the example by @vdukhovni the renamer produces the following very unfortunate code: {{{ Poly.main :: IO () Poly.main = do join (line_a1Wh <- getLine | locker_a1Wj <- do lock_a1Wi <- newMVar () let locker_a1Wj :: Poly.Locker locker_a1Wj = withMVar lock_a1Wi . const return locker_a1Wj) Poly.f line_a1Wh locker_a1Wj }}} It would have been much better if the let statement had been pulled out from inside the join and just on top of the last line. Indeed, if we change the example slightly we can actually make GHC accept the program: {{{ main :: IO () main = do line <- getLine lock <- newMVar () let locker :: Locker locker = withMVar lock . const res <- f line locker return res }}} The above program produces the following after renaming: {{{ main_a1Yv = do join (line_a1XS <- getLine | lock_a1XT <- newMVar ()) let locker_a1XU :: Locker locker_a1Z3 = withMVar lock_a1XT . const res_a1XV <- f line_a1XS locker_a1XU return res_a1XV }}} Just what we want! @vdukhovni, transforming let into where doesn't work in the general case unfortunately. Suppose that you had used either of the variables `line` or `lock` in your let statement. There would have been no way of transforming that into a where clause since those variables are not in scope in the where clause. -- Ticket URL: http://ghc.haskell.org/trac/ghc/ticket/11982#comment:11 GHC http://www.haskell.org/ghc/ The Glasgow Haskell Compiler