[GHC] #11982: Typechecking fails for parallel monad comprehensions with polymorphic let (GHC 7.10.3 through 8.6.3)

GHC ghc-devs at haskell.org
Fri Jan 25 17:01:32 UTC 2019


#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


More information about the ghc-tickets mailing list