I have this program Main.hs
:
main :: IO ()
main = do
if False then undefined
else do
let x = 5
print x
When I compile it with ghc Main.hs
it compils well generating a Main
executable, but when (after initializing cabal with cabal init
) I try to make a cabal new-run
it gives an error:
$ cabal new-run
Build profile: -w ghc-8.6.5 -O1
In order, the following will be built (use -v for more details):
- ghc-vs-cabal-0.1.0.0 (exe:ghc-vs-cabal) (file Main.hs changed)
Preprocessing executable 'ghc-vs-cabal' for ghc-vs-cabal-0.1.0.0..
Building executable 'ghc-vs-cabal' for ghc-vs-cabal-0.1.0.0..
[1 of 1] Compiling Main ( Main.hs, /home/ivan/ghc_vs_cabal/dist-newstyle/build/x86_64-linux/ghc-8.6.5/ghc-vs-cabal-0.1.0.0/x/ghc-vs-cabal/build/ghc-vs-cabal/ghc-vs-cabal-tmp/Main.o )
Main.hs:4:10: error: Empty 'do' block
|
4 | else do
| ^^
With cabal run
it also gives error.
I have cabal version 2.4.0.0
:
$ cabal --version
cabal-install version 2.4.0.0
compiled using version 2.4.0.1 of the Cabal library
And ghc version 8.6.5
:
$ ghc --version
The Glorious Glasgow Haskell Compilation System, version 8.6.5
Does somebody know what is happening?
I know that I can fix it if I add indentation:
main :: IO ()
main = do
if False then undefined
else do
let x = 5
print x
But I want to know why it compiles with ghc
but not with cabal new-run
CodePudding user response:
Your code requires a language extension to parse: NondecreasingIndentation
. This extension exists to avoid the awkward runaway effect of nested do
s
main :: IO ()
main = do
if False then undefined
else do -- next block should be indented in standard Haskell
let x = 5
print x -- ...but this can easily get out of hand if you do it multiple times
NondecreasingIndentation
allows a nested do
block to register as nested as long as it's indented as much as the containing block, instead of more than the container.
According to the GHC manual, NondecreasingIndentation
is on by default but disabled in Haskell2010
mode (unless explicitly enabled again). I can't find the corresponding cabal
documentation, but we can probably guess it defaults to specifying Haskell2010
.
You can specify extensions in a source file to be enabled or disabled regardless of external options by adding a pragma like
{-# LANGUAGE NondecreasingIndentation #-}
to the very top of the file.