GHC issueshttps://gitlab.haskell.org/ghc/ghc/-/issues2019-07-07T18:29:36Zhttps://gitlab.haskell.org/ghc/ghc/-/issues/11612Bug in ApplicativeDo2019-07-07T18:29:36ZSimon MarlowBug in ApplicativeDoI discovered a bug in `ApplicativeDo`. Fix coming shortly. The problem is illustrated by this test case, which I will add to `ado001.hs` in the testsuite:
```
test11 :: M ()
test11 = do
x1 <- a
let x2 = x1
x3 <- b
let x4 = c
...I discovered a bug in `ApplicativeDo`. Fix coming shortly. The problem is illustrated by this test case, which I will add to `ado001.hs` in the testsuite:
```
test11 :: M ()
test11 = do
x1 <- a
let x2 = x1
x3 <- b
let x4 = c
x5 = x4
return (const () (x1,x2,x3,x4))
```
Which should give `(a | b)`, but gives `(a ; b)` in 8.0.1 RC.
<details><summary>Trac metadata</summary>
| Trac field | Value |
| ---------------------- | ------------ |
| Version | 7.10.3 |
| Type | Bug |
| TypeOfFailure | OtherFailure |
| Priority | high |
| Resolution | Unresolved |
| Component | Compiler |
| Test case | |
| Differential revisions | |
| BlockedBy | |
| Related | |
| Blocking | |
| CC | |
| Operating system | |
| Architecture | |
</details>
<!-- {"blocked_by":[],"summary":"Bug in ApplicativeDo","status":"New","operating_system":"","component":"Compiler","related":[],"milestone":"8.0.1","resolution":"Unresolved","owner":{"tag":"Unowned"},"version":"7.10.3","keywords":[],"differentials":[],"test_case":"","architecture":"","cc":[""],"type":"Bug","description":"I discovered a bug in `ApplicativeDo`. Fix coming shortly. The problem is illustrated by this test case, which I will add to `ado001.hs` in the testsuite:\r\n\r\n{{{\r\ntest11 :: M ()\r\ntest11 = do\r\n x1 <- a\r\n let x2 = x1\r\n x3 <- b\r\n let x4 = c\r\n x5 = x4\r\n return (const () (x1,x2,x3,x4))\r\n}}}\r\n\r\nWhich should give `(a | b)`, but gives `(a ; b)` in 8.0.1 RC.","type_of_failure":"OtherFailure","blocking":[]} -->8.0.1https://gitlab.haskell.org/ghc/ghc/-/issues/11607ApplicativeDo easily foiled with `pure`2019-07-07T18:29:38ZBen GamariApplicativeDo easily foiled with `pure``ApplicativeDo` fails to desugar `do` blocks ending with `pure`. For instance,
```hs
{-# LANGUAGE ApplicativeDo #-}
{-# LANGUAGE GeneralizedNewtypeDeriving #-}
newtype MaybeA a = MaybeA (Maybe a)
deriving (Show, Functo...`ApplicativeDo` fails to desugar `do` blocks ending with `pure`. For instance,
```hs
{-# LANGUAGE ApplicativeDo #-}
{-# LANGUAGE GeneralizedNewtypeDeriving #-}
newtype MaybeA a = MaybeA (Maybe a)
deriving (Show, Functor, Applicative)
main = print $ do x <- MaybeA $ Just 42
pure x
```
However, if the final `pure` is changed to `return` things work as expected.
<details><summary>Trac metadata</summary>
| Trac field | Value |
| ---------------------- | ----------------------- |
| Version | 8.0.1-rc2 |
| Type | Bug |
| TypeOfFailure | OtherFailure |
| Priority | high |
| Resolution | Unresolved |
| Component | Compiler (Type checker) |
| Test case | |
| Differential revisions | |
| BlockedBy | |
| Related | |
| Blocking | |
| CC | simonmar |
| Operating system | |
| Architecture | |
</details>
<!-- {"blocked_by":[],"summary":"ApplicativeDo easily foiled with `pure`","status":"New","operating_system":"","component":"Compiler (Type checker)","related":[],"milestone":"8.0.1","resolution":"Unresolved","owner":{"tag":"Unowned"},"version":"8.0.1-rc2","keywords":["ApplicativeDo"],"differentials":[],"test_case":"","architecture":"","cc":["simonmar"],"type":"Bug","description":"`ApplicativeDo` fails to desugar `do` blocks ending with `pure`. For instance,\r\n{{{#!hs\r\n{-# LANGUAGE ApplicativeDo #-}\r\n{-# LANGUAGE GeneralizedNewtypeDeriving #-}\r\n\r\nnewtype MaybeA a = MaybeA (Maybe a)\r\n deriving (Show, Functor, Applicative)\r\n\r\nmain = print $ do x <- MaybeA $ Just 42\r\n pure x\r\n}}}\r\n\r\nHowever, if the final `pure` is changed to `return` things work as expected.","type_of_failure":"OtherFailure","blocking":[]} -->8.0.1Ben GamariBen Gamarihttps://gitlab.haskell.org/ghc/ghc/-/issues/10976Applicative Comprehensions2021-11-09T15:32:18ZdavidarApplicative ComprehensionsAs discussed on [ghc-devs](https://mail.haskell.org/pipermail/ghc-devs/2015-October/010062.html), when both the `MonadComprehensions` and `ApplicativeDo` language extensions are enabled, it should be possible to use comprehension-notatio...As discussed on [ghc-devs](https://mail.haskell.org/pipermail/ghc-devs/2015-October/010062.html), when both the `MonadComprehensions` and `ApplicativeDo` language extensions are enabled, it should be possible to use comprehension-notation (in addition to do-notation) for `Applicative`s. This would allow, for example, an expression like
```hs
(\x y -> x + 2*y) <$> ZipList [1..10] <*> ZipList [10,20..100]
```
to also be written as
```hs
[ x + 2*y | x <- ZipList [1..10], y <- ZipList [10,20..100] ]
```8.0.1https://gitlab.haskell.org/ghc/ghc/-/issues/12490With RebindableSyntax, ApplicativeDo should eliminate return/pure2019-07-07T18:26:23ZAaronFrielWith RebindableSyntax, ApplicativeDo should eliminate return/pureIn a module with -XApplicativeDo, -XRebindableSyntax, and local definitions for everything in the Functor-Applicative-Monad hierarchy, do-notation always desugars to "join (... (return ...))" (or /s/return/pure/). This forces the result ...In a module with -XApplicativeDo, -XRebindableSyntax, and local definitions for everything in the Functor-Applicative-Monad hierarchy, do-notation always desugars to "join (... (return ...))" (or /s/return/pure/). This forces the result to have at least the constraints of join, which in my case is "IxMonad m".
```hs
{-# LANGUAGE RebindableSyntax, ApplicativeDo #-}
module My where
-- straightforward definitions of fmap, pure, (<*>), join, return, (>>=),
-- (>>) and fail in terms of IxFunctor, IxPointed, IxApplicative, IxMonad
fPure m = do
a <- m
b <- m
pure (a, b)
fReturn m = do
a <- m
b <- m
return (a, b)
```
According to -ddump-ds, these desugar to:
```hs
fPure :: IxMonad m => m k1 k1 a -> m k1 k1 (a, a)
fPure m = My.join ( My.(<*>) (My.fmap (\a b -> My.pure (a, b)) m) m )
fReturn :: IxMonad m => m k1 k1 a -> m k1 k1 (a, a)
fReturn m = My.join ( My.(<*>) (My.fmap (\a b -> My.return (a, b)) m) m )
```
But I would expect:
```hs
fPure m = My.(<*>) (My.fmap (\a b -> (a, b)) m) m
fReturn m = -- same
```
It appears that when "return" is not from base, ApplicativeDo only partially desugars to the specification, and the final "return" or "pure" remains in the output.8.0.2Simon MarlowSimon Marlowhttps://gitlab.haskell.org/ghc/ghc/-/issues/11835ApplicativeDo failed to desugar last line with pure $ <expr>2019-07-07T18:28:20ZCosmiaApplicativeDo failed to desugar last line with pure $ <expr>```hs
{-# LANGUAGE ApplicativeDo #-}
f m = do
x <- m 1
y <- m 2
return $ x + y
```
f should have type (Applicative f, Num a, Num b) =\> (a -\> f b) -\> f b
but ghc considers f a monad
maybe similar with #11607
<details><summary>...```hs
{-# LANGUAGE ApplicativeDo #-}
f m = do
x <- m 1
y <- m 2
return $ x + y
```
f should have type (Applicative f, Num a, Num b) =\> (a -\> f b) -\> f b
but ghc considers f a monad
maybe similar with #11607
<details><summary>Trac metadata</summary>
| Trac field | Value |
| ---------------------- | ------------ |
| Version | 8.0.1-rc2 |
| Type | Bug |
| TypeOfFailure | OtherFailure |
| Priority | normal |
| Resolution | Unresolved |
| Component | Compiler |
| Test case | |
| Differential revisions | |
| BlockedBy | |
| Related | |
| Blocking | |
| CC | |
| Operating system | |
| Architecture | |
</details>
<!-- {"blocked_by":[],"summary":"ApplicativeDo failed to desugar last line with pure $ <expr>","status":"New","operating_system":"","component":"Compiler","related":[],"milestone":"","resolution":"Unresolved","owner":{"tag":"Unowned"},"version":"8.0.1-rc2","keywords":["ApplicativeDo"],"differentials":[],"test_case":"","architecture":"","cc":[""],"type":"Bug","description":"{{{#!hs\r\n{-# LANGUAGE ApplicativeDo #-}\r\nf m = do\r\n x <- m 1\r\n y <- m 2\r\n return $ x + y\r\n}}}\r\nf should have type (Applicative f, Num a, Num b) => (a -> f b) -> f b\r\nbut ghc considers f a monad\r\n\r\nmaybe similar with #11607","type_of_failure":"OtherFailure","blocking":[]} -->8.0.2Simon MarlowSimon Marlowhttps://gitlab.haskell.org/ghc/ghc/-/issues/13242Panic "StgCmmEnv: variable not found" with ApplicativeDo and ExistentialQuant...2019-07-07T18:22:57ZljliPanic "StgCmmEnv: variable not found" with ApplicativeDo and ExistentialQuantification```hs
-- Panic.hs
{-# LANGUAGE ApplicativeDo #-}
{-# LANGUAGE ExistentialQuantification #-}
module Panic where
import Data.STRef
import Control.Monad.ST
data A = forall a. A a
st :: ST s ()
st = do
A _ <- pure $ A True
ref...```hs
-- Panic.hs
{-# LANGUAGE ApplicativeDo #-}
{-# LANGUAGE ExistentialQuantification #-}
module Panic where
import Data.STRef
import Control.Monad.ST
data A = forall a. A a
st :: ST s ()
st = do
A _ <- pure $ A True
ref <- newSTRef 1
readSTRef ref
pure ()
```
```
$ ghc Panic.hs
[1 of 1] Compiling Panic ( Panic.hs, Panic.o )
ghc: panic! (the 'impossible' happened)
(GHC version 8.1.20170106 for x86_64-unknown-linux):
StgCmmEnv: variable not found
$dMonad_aGQ
local binds for:
$trModule
$tcA
$tc'A
$tcA1_rSi
$tc'A1_rSJ
$trModule1_rSK
$trModule2_rSL
sat_sT5
sat_sT9
sat_sTa
Call stack:
CallStack (from HasCallStack):
prettyCurrentCallStack, called at compiler/utils/Outputable.hs:1133:58 in ghc:Outputable
callStackDoc, called at compiler/utils/Outputable.hs:1137:37 in ghc:Outputable
pprPanic, called at compiler/codeGen/StgCmmEnv.hs:137:9 in ghc:StgCmmEnv
Please report this as a GHC bug: http://www.haskell.org/ghc/reportabug
```
The above module fails to compile, giving the pasted panic message.
Without the ApplicativeDo pragma compilation succeeds.
Reproduced with GHC 8.0.2 and a recent head, courtesy of nixpkgs:
```
gp84vpgar3n3rqvkwj47yyhxvsvbsmi6-ghc-8.1.20170106
```
<details><summary>Trac metadata</summary>
| Trac field | Value |
| ---------------------- | ------------ |
| Version | 8.1 |
| Type | Bug |
| TypeOfFailure | OtherFailure |
| Priority | normal |
| Resolution | Unresolved |
| Component | Compiler |
| Test case | |
| Differential revisions | |
| BlockedBy | |
| Related | |
| Blocking | |
| CC | |
| Operating system | |
| Architecture | |
</details>
<!-- {"blocked_by":[],"summary":"Panic \"StgCmmEnv: variable not found\" with ApplicativeDo and ExistentialQuantification","status":"New","operating_system":"","component":"Compiler","related":[],"milestone":"","resolution":"Unresolved","owner":{"tag":"Unowned"},"version":"8.1","keywords":[],"differentials":[],"test_case":"","architecture":"","cc":[""],"type":"Bug","description":"{{{#!hs\r\n-- Panic.hs\r\n{-# LANGUAGE ApplicativeDo #-}\r\n{-# LANGUAGE ExistentialQuantification #-}\r\nmodule Panic where\r\n\r\nimport Data.STRef\r\nimport Control.Monad.ST\r\n\r\ndata A = forall a. A a\r\n\r\nst :: ST s ()\r\nst = do\r\n A _ <- pure $ A True\r\n ref <- newSTRef 1\r\n readSTRef ref\r\n pure ()\r\n}}}\r\n\r\n{{{\r\n$ ghc Panic.hs\r\n[1 of 1] Compiling Panic ( Panic.hs, Panic.o )\r\nghc: panic! (the 'impossible' happened)\r\n (GHC version 8.1.20170106 for x86_64-unknown-linux):\r\n\tStgCmmEnv: variable not found\r\n $dMonad_aGQ\r\n local binds for:\r\n $trModule\r\n $tcA\r\n $tc'A\r\n $tcA1_rSi\r\n $tc'A1_rSJ\r\n $trModule1_rSK\r\n $trModule2_rSL\r\n sat_sT5\r\n sat_sT9\r\n sat_sTa\r\n Call stack:\r\n CallStack (from HasCallStack):\r\n prettyCurrentCallStack, called at compiler/utils/Outputable.hs:1133:58 in ghc:Outputable\r\n callStackDoc, called at compiler/utils/Outputable.hs:1137:37 in ghc:Outputable\r\n pprPanic, called at compiler/codeGen/StgCmmEnv.hs:137:9 in ghc:StgCmmEnv\r\n\r\nPlease report this as a GHC bug: http://www.haskell.org/ghc/reportabug\r\n}}}\r\n\r\nThe above module fails to compile, giving the pasted panic message.\r\nWithout the ApplicativeDo pragma compilation succeeds.\r\nReproduced with GHC 8.0.2 and a recent head, courtesy of nixpkgs:\r\n{{{\r\ngp84vpgar3n3rqvkwj47yyhxvsvbsmi6-ghc-8.1.20170106\r\n}}}","type_of_failure":"OtherFailure","blocking":[]} -->8.2.1Simon MarlowSimon Marlowhttps://gitlab.haskell.org/ghc/ghc/-/issues/13875ApplicativeDo desugaring is lazier than standard desugaring2019-07-07T18:19:43ZDavid FeuerApplicativeDo desugaring is lazier than standard desugaringSuppose I write
```hs
import Data.Maybe (isJust)
bangy m = do
(_,_) <- m
return ()
main = print $ isJust (bangy (Just undefined))
```
If I compile this with `ApplicativeDo`, it prints `True`. Otherwise, it throws an exception. Th...Suppose I write
```hs
import Data.Maybe (isJust)
bangy m = do
(_,_) <- m
return ()
main = print $ isJust (bangy (Just undefined))
```
If I compile this with `ApplicativeDo`, it prints `True`. Otherwise, it throws an exception. The basic problem is that the (correct) `bangy` function *requires* a `Monad` constraint, but `ApplicativeDo` replaces it with a lazier function that can get by with `Functor`. I believe it should desugar correctly, and impose a `Monad` constraint here. To get the `Functor` constraint should require an explicit lazy pattern match:
```hs
bangy m = do
~(_,_) <- m
return ()
```
<details><summary>Trac metadata</summary>
| Trac field | Value |
| ---------------------- | ------------ |
| Version | 8.3 |
| Type | Bug |
| TypeOfFailure | OtherFailure |
| Priority | normal |
| Resolution | Unresolved |
| Component | Compiler |
| Test case | |
| Differential revisions | |
| BlockedBy | |
| Related | |
| Blocking | |
| CC | simonmar |
| Operating system | |
| Architecture | |
</details>
<!-- {"blocked_by":[],"summary":"ApplicativeDo desugaring is lazier than standard desugaring","status":"New","operating_system":"","component":"Compiler","related":[],"milestone":"8.4.1","resolution":"Unresolved","owner":{"tag":"Unowned"},"version":"8.3","keywords":["ApplicativeDo"],"differentials":[],"test_case":"","architecture":"","cc":["simonmar"],"type":"Bug","description":"Suppose I write\r\n\r\n{{{#!hs\r\nimport Data.Maybe (isJust)\r\n\r\nbangy m = do\r\n (_,_) <- m\r\n return ()\r\n\r\nmain = print $ isJust (bangy (Just undefined))\r\n}}}\r\n\r\nIf I compile this with `ApplicativeDo`, it prints `True`. Otherwise, it throws an exception. The basic problem is that the (correct) `bangy` function ''requires'' a `Monad` constraint, but `ApplicativeDo` replaces it with a lazier function that can get by with `Functor`. I believe it should desugar correctly, and impose a `Monad` constraint here. To get the `Functor` constraint should require an explicit lazy pattern match:\r\n\r\n{{{#!hs\r\nbangy m = do\r\n ~(_,_) <- m\r\n return ()\r\n}}}","type_of_failure":"OtherFailure","blocking":[]} -->8.2.1Simon MarlowSimon Marlowhttps://gitlab.haskell.org/ghc/ghc/-/issues/14163Stack Overflow with ApplicativeDo2019-07-07T18:18:12ZlipplingStack Overflow with ApplicativeDoI tried to compile one of our server applications with 8.2.1 (which compiles fine with 8.0.2).
The compilation runs smoothly, but when it reaches a specific file, the RAM usage goes up to \> 20GB pretty fast on my 16GB machine and the G...I tried to compile one of our server applications with 8.2.1 (which compiles fine with 8.0.2).
The compilation runs smoothly, but when it reaches a specific file, the RAM usage goes up to \> 20GB pretty fast on my 16GB machine and the GHC process gets terminated with a stack overflow error.
I tried to find a minimal example that causes this behavior:
```hs
#!/usr/bin/env stack
-- stack --resolver nightly-2017-08-25 script
{-# LANGUAGE ApplicativeDo #-}
x = do
(a, _) <- undefined
(b, _) <- undefined
(c, _) <- undefined
undefined
main = undefined
```
It only happens with at least 3 of these pattern matches.8.2.2Simon MarlowSimon Marlowhttps://gitlab.haskell.org/ghc/ghc/-/issues/14105ApplicativeDo causes GHC panic on irrefutable list pattern match2019-07-07T18:18:27ZBoteboTseboApplicativeDo causes GHC panic on irrefutable list pattern matchSo this just happened:
```hs
{-# language ApplicativeDo #-}
module Main where
main :: IO ()
main = do
[_] <- pure []
pure ()
```
Compiling (under Stack) with `stack exec -- ghc --make src/Main.hs` yields
```
[1 of 1] Compiling Ma...So this just happened:
```hs
{-# language ApplicativeDo #-}
module Main where
main :: IO ()
main = do
[_] <- pure []
pure ()
```
Compiling (under Stack) with `stack exec -- ghc --make src/Main.hs` yields
```
[1 of 1] Compiling Main ( src/Main.hs, src/Main.o )
ghc: panic! (the 'impossible' happened)
(GHC version 8.2.1 for x86_64-unknown-linux):
isStrictPattern
Please report this as a GHC bug: http://www.haskell.org/ghc/reportabug
```
This does not happen on GHC-8.0.2. It does not happen when `ApplicativeDo` is not activated. It also does not happen when the pattern match line is changed to
```hs
[] <- pure []
```
For completeness, the compiler used by `stack` is that which comes with `nightly-2017-08-10`. I am on Linux x64 (Ubuntu).
<details><summary>Trac metadata</summary>
| Trac field | Value |
| ---------------------- | ------------ |
| Version | 8.2.1 |
| Type | Bug |
| TypeOfFailure | OtherFailure |
| Priority | normal |
| Resolution | Unresolved |
| Component | Compiler |
| Test case | |
| Differential revisions | |
| BlockedBy | |
| Related | |
| Blocking | |
| CC | |
| Operating system | |
| Architecture | |
</details>
<!-- {"blocked_by":[],"summary":"ApplicativeDo causes GHC panic on irrefutable list pattern match","status":"New","operating_system":"","component":"Compiler","related":[],"milestone":"","resolution":"Unresolved","owner":{"tag":"Unowned"},"version":"8.2.1","keywords":["ApplicativeDo"],"differentials":[],"test_case":"","architecture":"","cc":[""],"type":"Bug","description":"So this just happened:\r\n\r\n{{{#!hs\r\n{-# language ApplicativeDo #-}\r\nmodule Main where\r\n\r\nmain :: IO ()\r\nmain = do\r\n [_] <- pure []\r\n pure ()\r\n}}}\r\n\r\nCompiling (under Stack) with `stack exec -- ghc --make src/Main.hs` yields\r\n{{{\r\n[1 of 1] Compiling Main ( src/Main.hs, src/Main.o )\r\nghc: panic! (the 'impossible' happened)\r\n (GHC version 8.2.1 for x86_64-unknown-linux):\r\n\tisStrictPattern\r\n\r\nPlease report this as a GHC bug: http://www.haskell.org/ghc/reportabug\r\n}}}\r\n\r\nThis does not happen on GHC-8.0.2. It does not happen when `ApplicativeDo` is not activated. It also does not happen when the pattern match line is changed to\r\n{{{#!hs\r\n [] <- pure []\r\n}}}\r\n\r\n\r\nFor completeness, the compiler used by `stack` is that which comes with `nightly-2017-08-10`. I am on Linux x64 (Ubuntu).","type_of_failure":"OtherFailure","blocking":[]} -->8.4.1https://gitlab.haskell.org/ghc/ghc/-/issues/12143ApplicativeDo Fails to Desugar 'return True'2019-07-07T18:27:29ZMichaelBurgeApplicativeDo Fails to Desugar 'return True'ApplicativeDo correctly infers Functor if I bind an unused variable:
```
Prelude> :t \m -> do { x <- m; return True; }
\m -> do { x <- m; return True; } :: Functor f => f t -> f Bool
Prelude> :t \m -> do { m; return True; }
\m -> do { ...ApplicativeDo correctly infers Functor if I bind an unused variable:
```
Prelude> :t \m -> do { x <- m; return True; }
\m -> do { x <- m; return True; } :: Functor f => f t -> f Bool
Prelude> :t \m -> do { m; return True; }
\m -> do { m; return True; } :: Monad m => m a -> m Bool
```
It seems like if 'x' is unused, then 'x \<- m' and 'm' should be equivalent.
And maybe 'return True' should be Monad, but 'do { return True; }' should be Applicative?8.4.1Simon MarlowSimon Marlowhttps://gitlab.haskell.org/ghc/ghc/-/issues/15016Referencing a do-bound variable in a rec block with ApplicativeDo results in ...2021-08-06T00:14:44ZrjmkReferencing a do-bound variable in a rec block with ApplicativeDo results in variable not in scope during type checkingI searched + hope this isn't a dupe.
When using both ApplicativeDo and RecursiveDo, referring to a do-bound variable from outside of a rec block causes a GHC internal error.
Here's a minimal example:
```hs
{-# LANGUAGE ApplicativeDo #...I searched + hope this isn't a dupe.
When using both ApplicativeDo and RecursiveDo, referring to a do-bound variable from outside of a rec block causes a GHC internal error.
Here's a minimal example:
```hs
{-# LANGUAGE ApplicativeDo #-}
{-# LANGUAGE RecursiveDo #-}
module Lib where
import Control.Monad.Fix
f :: MonadFix m => m ()
f = do
a <- return ()
rec
let b = a
return ()
```
The error message I get is
```
src/Lib.hs:12:13: error:
• GHC internal error: ‘a’ is not in scope during type checking, but it passed the renamer
tcl_env of environment: [a1pF :-> Type variable ‘m’ = m :: * -> *,
r1mX :-> Identifier[f::forall (m :: * -> *).
MonadFix m =>
m (), TopLevelLet [] True]]
• In the expression: a
In an equation for ‘b’: b = a
In a stmt of a 'do' block: rec let b = a
|
12 | let b = a
| ^
```
I have reproduced it in 8.2.2 and 8.4.1
<details><summary>Trac metadata</summary>
| Trac field | Value |
| ---------------------- | ------------ |
| Version | 8.2.2 |
| Type | Bug |
| TypeOfFailure | OtherFailure |
| Priority | normal |
| Resolution | Unresolved |
| Component | Compiler |
| Test case | |
| Differential revisions | |
| BlockedBy | |
| Related | |
| Blocking | |
| CC | |
| Operating system | |
| Architecture | |
</details>
<!-- {"blocked_by":[],"summary":"Referencing a do-bound variable in a rec block with ApplicativeDo results in variable not in scope during type checking","status":"New","operating_system":"","component":"Compiler","related":[],"milestone":"8.4.3","resolution":"Unresolved","owner":{"tag":"Unowned"},"version":"8.2.2","keywords":[],"differentials":[],"test_case":"","architecture":"","cc":[""],"type":"Bug","description":"I searched + hope this isn't a dupe.\r\n\r\nWhen using both ApplicativeDo and RecursiveDo, referring to a do-bound variable from outside of a rec block causes a GHC internal error.\r\n\r\nHere's a minimal example:\r\n\r\n{{{#!hs\r\n{-# LANGUAGE ApplicativeDo #-}\r\n{-# LANGUAGE RecursiveDo #-}\r\n\r\nmodule Lib where\r\n\r\nimport Control.Monad.Fix\r\n\r\nf :: MonadFix m => m ()\r\nf = do\r\n a <- return ()\r\n rec\r\n let b = a\r\n return ()\r\n}}}\r\n\r\nThe error message I get is\r\n\r\n\r\n{{{\r\nsrc/Lib.hs:12:13: error:\r\n • GHC internal error: ‘a’ is not in scope during type checking, but it passed the renamer\r\n tcl_env of environment: [a1pF :-> Type variable ‘m’ = m :: * -> *,\r\n r1mX :-> Identifier[f::forall (m :: * -> *).\r\n MonadFix m =>\r\n m (), TopLevelLet [] True]]\r\n • In the expression: a\r\n In an equation for ‘b’: b = a\r\n In a stmt of a 'do' block: rec let b = a\r\n |\r\n12 | let b = a\r\n | ^\r\n}}}\r\n\r\n\r\nI have reproduced it in 8.2.2 and 8.4.1\r\n","type_of_failure":"OtherFailure","blocking":[]} -->8.4.3Simon MarlowSimon Marlowhttps://gitlab.haskell.org/ghc/ghc/-/issues/15422GHCi debugger doesn't see free variables when using ApplicativeDo2019-07-07T18:04:58ZSimon MarlowGHCi debugger doesn't see free variables when using ApplicativeDo```
> ghci break029.hs
GHCi, version 8.2.2: http://www.haskell.org/ghc/ :? for help
[1 of 1] Compiling Main ( break029.hs, interpreted )
Ok, one module loaded.
*Main> :!cat break029.hs
{-# LANGUAGE ApplicativeDo #-}
f :: In...```
> ghci break029.hs
GHCi, version 8.2.2: http://www.haskell.org/ghc/ :? for help
[1 of 1] Compiling Main ( break029.hs, interpreted )
Ok, one module loaded.
*Main> :!cat break029.hs
{-# LANGUAGE ApplicativeDo #-}
f :: Int -> IO Int
f x = do
y <- return (x + 1)
return (y * 2)
*Main> :step f 3
Stopped in Main.f, break029.hs:(4,7)-(6,16)
_result :: IO Int = _
x :: Int = 3
[break029.hs:(4,7)-(6,16)] [break029.hs:(4,7)-(6,16)] *Main> :list
3 f :: Int -> IO Int
4 f x = do
5 y <- return (x + 1)
6 return (y * 2)
7
[break029.hs:(4,7)-(6,16)] [break029.hs:(4,7)-(6,16)] *Main> :step
Stopped in Main.f, break029.hs:5:8-21
_result :: IO Int = _
x :: Int = 3
[break029.hs:5:8-21] [break029.hs:5:8-21] *Main> :list
4 f x = do
5 y <- return (x + 1)
6 return (y * 2)
[break029.hs:5:8-21] [break029.hs:5:8-21] *Main> :step
Stopped in Main.f, break029.hs:6:11-15
_result :: Int = _
[break029.hs:6:11-15] [break029.hs:6:11-15] *Main> y
<interactive>:7:1: error: Variable not in scope: y
```8.6.1https://gitlab.haskell.org/ghc/ghc/-/issues/14471Certain do blocks cause TH to barf when ApplicativeDo is enabled2019-07-07T18:16:54ZAlexis KingCertain do blocks cause TH to barf when ApplicativeDo is enabledThe following program fails with an error:
```hs
{-# LANGUAGE ApplicativeDo #-}
{-# LANGUAGE TemplateHaskell #-}
main = $([|do
return ()
return ()
return ()|])
```
```
Exotic.hs:4:12: error:
Exotic statement not (yet) handle...The following program fails with an error:
```hs
{-# LANGUAGE ApplicativeDo #-}
{-# LANGUAGE TemplateHaskell #-}
main = $([|do
return ()
return ()
return ()|])
```
```
Exotic.hs:4:12: error:
Exotic statement not (yet) handled by Template Haskell
[return ();
return (),
return ()]
```
It only happens when `ApplicativeDo` is enabled.
Furthermore, while this example is extremely minimal, this issue isn’t restricted to `ApplicativeDo`’s special handling of `return`. The following example produces the same error:
```hs
{-# LANGUAGE ApplicativeDo #-}
{-# LANGUAGE TemplateHaskell #-}
main = $([|do
getLine
getLine
getLine|])
```
```
Exotic.hs:4:12: error:
Exotic statement not (yet) handled by Template Haskell
[getLine;
getLine,
getLine]
```
This *doesn’t* happen with fewer than three statements in the `do` block, but it *does* happen with more.
<details><summary>Trac metadata</summary>
| Trac field | Value |
| ---------------------- | ---------------- |
| Version | 8.2.1 |
| Type | Bug |
| TypeOfFailure | OtherFailure |
| Priority | normal |
| Resolution | Unresolved |
| Component | Template Haskell |
| Test case | |
| Differential revisions | |
| BlockedBy | |
| Related | |
| Blocking | |
| CC | |
| Operating system | |
| Architecture | |
</details>
<!-- {"blocked_by":[],"summary":"Certain do blocks cause TH to barf when ApplicativeDo is enabled","status":"New","operating_system":"","component":"Template Haskell","related":[],"milestone":"","resolution":"Unresolved","owner":{"tag":"Unowned"},"version":"8.2.1","keywords":[],"differentials":[],"test_case":"","architecture":"","cc":[""],"type":"Bug","description":"The following program fails with an error:\r\n\r\n{{{#!hs\r\n{-# LANGUAGE ApplicativeDo #-}\r\n{-# LANGUAGE TemplateHaskell #-}\r\n\r\nmain = $([|do\r\n return ()\r\n return ()\r\n return ()|])\r\n}}}\r\n{{{\r\nExotic.hs:4:12: error:\r\n Exotic statement not (yet) handled by Template Haskell\r\n [return ();\r\n return (),\r\n return ()]\r\n}}}\r\n\r\nIt only happens when `ApplicativeDo` is enabled.\r\n\r\nFurthermore, while this example is extremely minimal, this issue isn’t restricted to `ApplicativeDo`’s special handling of `return`. The following example produces the same error:\r\n\r\n{{{#!hs\r\n{-# LANGUAGE ApplicativeDo #-}\r\n{-# LANGUAGE TemplateHaskell #-}\r\n\r\nmain = $([|do\r\n getLine\r\n getLine\r\n getLine|])\r\n}}}\r\n{{{\r\nExotic.hs:4:12: error:\r\n Exotic statement not (yet) handled by Template Haskell\r\n [getLine;\r\n getLine,\r\n getLine]\r\n}}}\r\n\r\nThis ''doesn’t'' happen with fewer than three statements in the `do` block, but it ''does'' happen with more.","type_of_failure":"OtherFailure","blocking":[]} -->8.6.1Michael SloanMichael Sloanhttps://gitlab.haskell.org/ghc/ghc/-/issues/17835Regression with ApplicativeDo in 8.10-rc12020-04-08T07:45:03ZadamRegression with ApplicativeDo in 8.10-rc1This program fails to compile in GHC 8.10-rc1:
```haskell
-- Build.hs
{-# LANGUAGE ApplicativeDo #-}
module Build (configRules) where
type Action = IO
type Rules = IO
type Config = ()
(%>) :: String -> (String -> Action ()) -> Rules ...This program fails to compile in GHC 8.10-rc1:
```haskell
-- Build.hs
{-# LANGUAGE ApplicativeDo #-}
module Build (configRules) where
type Action = IO
type Rules = IO
type Config = ()
(%>) :: String -> (String -> Action ()) -> Rules ()
(%>) = undefined
command_ :: [String] -> String -> [String] -> Action ()
command_ = undefined
recursive :: Config -> String -> [String] -> IO (FilePath, [String])
recursive = undefined
liftIO :: IO a -> Action a
liftIO = id
need :: [String] -> Action ()
need = undefined
historyDisable :: Action ()
historyDisable = undefined
get_config :: () -> Action Config
get_config = undefined
configRules :: Rules ()
configRules = do
"snapshot" %> \out -> do
historyDisable -- 8.10-rc1 refuses to compile without bind here
config <- get_config ()
need []
(exe,args) <- liftIO $ recursive config "snapshot" []
command_ [] exe args
```
```
$ ghc --version
The Glorious Glasgow Haskell Compilation System, version 8.10.0.20200123
$ ghc -c Build.hs -fforce-recomp
Build.hs:38:5: error:
• Couldn't match expected type ‘IO ([String], String)’
with actual type ‘([String], FilePath)’
• In the expression:
do historyDisable
config <- get_config ()
need []
(exe, args) <- liftIO $ recursive config "snapshot" []
command_ [] exe args
In the second argument of ‘(%>)’, namely
‘\ out
-> do historyDisable
config <- get_config ()
need []
(exe, args) <- liftIO $ recursive config "snapshot" []
command_ [] exe args’
In a stmt of a 'do' block:
"snapshot"
%>
\ out
-> do historyDisable
config <- get_config ()
need []
(exe, args) <- liftIO $ recursive config "snapshot" []
command_ [] exe args
|
38 | config <- get_config ()
| ^^^^^^
```
If I instead write `() <- historyDisable` compilation works.8.10.1https://gitlab.haskell.org/ghc/ghc/-/issues/15344ApplicativeDo seems to prevent the fail method from being used2020-04-08T07:45:03ZkccqzyApplicativeDo seems to prevent the fail method from being usedI 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...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
```hs
{-# 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.
<details><summary>Trac metadata</summary>
| Trac field | Value |
| ---------------------- | ------------ |
| Version | 8.2.2 |
| Type | Bug |
| TypeOfFailure | OtherFailure |
| Priority | normal |
| Resolution | Unresolved |
| Component | Compiler |
| Test case | |
| Differential revisions | |
| BlockedBy | |
| Related | |
| Blocking | |
| CC | |
| Operating system | |
| Architecture | |
</details>
<!-- {"blocked_by":[],"summary":"ApplicativeDo seems to prevent the fail method from being used","status":"New","operating_system":"","component":"Compiler","related":[],"milestone":"8.6.1","resolution":"Unresolved","owner":{"tag":"Unowned"},"version":"8.2.2","keywords":[],"differentials":[],"test_case":"","architecture":"","cc":[""],"type":"Bug","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.\r\n\r\nIf I have a module like this\r\n\r\n{{{#!hs\r\n{-# LANGUAGE ApplicativeDo #-}\r\n{-# OPTIONS_ghc -ddump-simpl #-}\r\nmodule M where\r\n\r\nf :: Maybe (Maybe Int) -> Maybe Int -> Maybe Int\r\nf mgs mid = do\r\n _ <- mid\r\n (Just moi) <- mgs\r\n pure (moi + 42)\r\n\r\nmain :: IO ()\r\nmain = print (f (Just Nothing) (Just 2))\r\n\r\n}}}\r\n\r\nThis will result in a runtime exception:\r\n\r\n{{{\r\nJust *** Exception: repro.hs:(6,13)-(9,17): Non-exhaustive patterns in lambda\r\n}}}\r\n\r\nBut if I remove the ApplicativeDo extension, this code works as normal, producing Nothing as the output.\r\n\r\nOn 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 \r\n\r\n> Your code should just work as before when ApplicativeDo is enabled, provided you use conventional Applicative instances.\r\n\r\nIf this is not a defect in GHC itself, I'd say it is a defect in documentation in not pointing out this gotcha.","type_of_failure":"OtherFailure","blocking":[]} -->8.10.1https://gitlab.haskell.org/ghc/ghc/-/issues/16628GHC doesn't catch missing MonadFail constraint with -XApplicativeDo2019-10-28T13:37:31ZSimon JakobiGHC 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 `-...```
-- 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 https://gitlab.haskell.org/ghc/ghc/issues/15344.8.10.1https://gitlab.haskell.org/ghc/ghc/-/issues/20630ApplicativeDo breaks uses of ImplicitParameters2022-08-15T16:04:37ZKhudyakovApplicativeDo breaks uses of ImplicitParameters## Summary
## Steps to reproduce
Following programs stops compiling if ApplicativeDo is enabled.
```haskell
-- {-# LANGUAGE ApplicativeDo #-}
{-# LANGUAGE ImplicitParams #-}
module Implicit where
implicit1, implicit2 :: (?ctx :: In...## Summary
## Steps to reproduce
Following programs stops compiling if ApplicativeDo is enabled.
```haskell
-- {-# LANGUAGE ApplicativeDo #-}
{-# LANGUAGE ImplicitParams #-}
module Implicit where
implicit1, implicit2 :: (?ctx :: Int) => IO Int
implicit1 = pure ?ctx
implicit2 = pure ?ctx
body :: IO Int
body = do
let ?ctx = 12 :: Int
x <- implicit1
y <- implicit2
pure $ x + y
```
with following error
```
/home/alexey/qqq/vector/implicit-do.hs:13:8: error:
• Unbound implicit parameter (?ctx::Int)
arising from a use of ‘implicit2’
• In a stmt of a 'do' block: y <- implicit2
In the expression: <<... snip ...>>
In an equation for ‘body’: <<... snip ...>>
```
Presumably this is because GHC desugars do-block using applicatives and this messes up scope of implicits.
## Expected behavior
I think that `?ctx` should be visible over rest of do block.
In program where this issue arose I tried to enable applicative do and it broke another function which happened to bind implicit parameters in do block.
## Environment
* GHC version used: 8.10.4, 9.2.0.202108219.4.3sheafsam.derbyshire@gmail.comsheafsam.derbyshire@gmail.comhttps://gitlab.haskell.org/ghc/ghc/-/issues/24418Add a warning when ApplicativeDo changes to monadic do2024-02-16T06:52:41ZhololeapAdd a warning when ApplicativeDo changes to monadic doCould we please get a warning when a module that has ApplicativeDo enabled is using monadic do instead? I understand this would be an annoying warning for -Wall, but it could be useful to enable per-module so that you know when a do bloc...Could we please get a warning when a module that has ApplicativeDo enabled is using monadic do instead? I understand this would be an annoying warning for -Wall, but it could be useful to enable per-module so that you know when a do block is using a Monad instance instead of an Applicative instance. Currently, there doesn't seem to be any sort of user feedback to indicate this change and there are many subtle things that can trigger this behavior.https://gitlab.haskell.org/ghc/ghc/-/issues/24406Applicative Do should go via HsExpansion Route2024-03-28T05:02:38ZApoorv IngleApplicative Do should go via HsExpansion Route## Summary
Impredicativity does not play well with `do`-blocks expanding under `ApplicativeDo` Language pragma due to ill-designed `tcSyntaxOp` (c.f. issues documented in [wiki page](https://gitlab.haskell.org/ghc/ghc/-/wikis/Rebindable...## Summary
Impredicativity does not play well with `do`-blocks expanding under `ApplicativeDo` Language pragma due to ill-designed `tcSyntaxOp` (c.f. issues documented in [wiki page](https://gitlab.haskell.org/ghc/ghc/-/wikis/Rebindable-syntax))
## Steps to reproduce
```haskell
-- test.hs
{-# LANGUAGE ImpredicativeTypes, ApplicativeDo #-}
module T where
t :: IO (forall a. a -> a)
t = return id
p :: (forall a. a -> a) -> (Bool, Int)
p f = (f True, f 3)
-- This typechecks (with QL)
foo1 = t >>= \x -> return (p x)
-- But this does *not* type check:
foo2 = do { x <- t ; return (p x) }
```
```
$ ghc test.hs
```
Error:
```
test.hs:14:18: error: [GHC-91028]
• Couldn't match type ‘a0’ with ‘forall a. a -> a’
Expected: IO a0
Actual: IO (forall a. a -> a)
Cannot instantiate unification variable ‘a0’
with a type involving polytypes: forall a. a -> a
• In a stmt of a 'do' block: x <- t
In the expression:
do x <- t
return (p x)
In an equation for ‘foo2’:
foo2
= do x <- t
return (p x)
|
14 | foo2 = do { x <- t ; return (p x) }
| ^
test.hs:14:32: error: [GHC-46956]
• Couldn't match expected type ‘a -> a’ with actual type ‘a0’
because type variable ‘a’ would escape its scope
This (rigid, skolem) type variable is bound by
a type expected by the context:
forall a. a -> a
at test.hs:14:32
• In the first argument of ‘p’, namely ‘x’
In a stmt of a 'do' block: return (p x)
In the expression:
do x <- t
return (p x)
• Relevant bindings include x :: a0 (bound at test.hs:14:13)
|
14 | foo2 = do { x <- t ; return (p x) }
```
## Expected behavior
It should type check and execute as expected
## Environment
* GHC version used: 9.6, 9.9Apoorv IngleApoorv Inglehttps://gitlab.haskell.org/ghc/ghc/-/issues/23692ApplicativeDo breaks typechecking2023-07-25T14:22:12ZSergey VinokurovApplicativeDo breaks typechecking## Summary
When enabling the `ApplicativeDo` extension the provided program ceases to typecheck. It does work in 9.4.5 and does work if I move `putStrLn` around or remove it entirely, which is surprising. Removing `ApplicativeDo` extens...## Summary
When enabling the `ApplicativeDo` extension the provided program ceases to typecheck. It does work in 9.4.5 and does work if I move `putStrLn` around or remove it entirely, which is surprising. Removing `ApplicativeDo` extension also helps but I'd like to get its effects in `parseCommandLine` function (omitted here for brevity).
## Steps to reproduce
Compile the following program.
Original program:
```haskell
{-# LANGUAGE ApplicativeDo #-}
module Main (main) where
import Control.Monad
data Command
= PolyCmd
| VanillaCmd
data CommonConfig = CommonConfig
{ ccVerbose :: Bool
}
parseCommandline :: IO (CommonConfig, Command)
parseCommandline = undefined
locateHelper :: FilePath -> IO (Maybe FilePath)
locateHelper = undefined
complexWrapper :: IO a -> IO a
complexWrapper = undefined
vanillaRun :: IO ()
vanillaRun = pure ()
polyRun :: (forall a. IO a -> IO a) -> IO ()
polyRun f = f $ pure ()
main :: IO ()
main = do
(config, cmd) <- parseCommandline
when (ccVerbose config) $
putStrLn "OK"
let wrapper :: IO a -> IO a
wrapper act = do
complexWrapper act
case cmd of
VanillaCmd -> wrapper vanillaRun
PolyCmd -> polyRun wrapper
```
```
$ ghc -c Main.hs
Main.hs:42:27: error: [GHC-25897]
• Couldn't match type ‘a’ with ‘()’
Expected: IO a -> IO a
Actual: IO () -> IO ()
‘a’ is a rigid type variable bound by
a type expected by the context:
forall a. IO a -> IO a
at Main.hs:42:27-33
• In the first argument of ‘polyRun’, namely ‘wrapper’
In the expression: polyRun wrapper
In a case alternative: PolyCmd -> polyRun wrapper
|
42 | PolyCmd -> polyRun wrapper
| ^^^^^^^
```
However this one does typecheck
```haskell
{-# LANGUAGE ApplicativeDo #-}
module Main (main) where
import Control.Monad
data Command
= PolyCmd
| VanillaCmd
data CommonConfig = CommonConfig
{ ccVerbose :: Bool
}
parseCommandline :: IO (CommonConfig, Command)
parseCommandline = undefined
locateHelper :: FilePath -> IO (Maybe FilePath)
locateHelper = undefined
complexWrapper :: IO a -> IO a
complexWrapper = undefined
vanillaRun :: IO ()
vanillaRun = pure ()
polyRun :: (forall a. IO a -> IO a) -> IO ()
polyRun f = f $ pure ()
main :: IO ()
main = do
(config, cmd) <- parseCommandline
let wrapper :: IO a -> IO a
wrapper act = do
when (ccVerbose config) $
putStrLn "OK"
complexWrapper act
case cmd of
VanillaCmd -> wrapper vanillaRun
PolyCmd -> polyRun wrapper
```
Commenting out `ApplicativeDo` also makes the original program typecheck.
## Expected behavior
Original program typechecks successfully with `ApplicativeDo` extension enabled.
## Environment
* GHC version used: 9.6.2
Optional:
* Operating System: Linux
* System Architecture: x86_64