使用 ghc 编译但不使用 cabal new-运行 编译的代码

Code that compiles with ghc but not with cabal new-run

我有这个程序Main.hs:

main :: IO ()
main = do
    if False then undefined 
    else do
    let x = 5
    print x

当我用 ghc Main.hs 编译它时,它编译生成一个 Main 可执行文件,但是当(在用 cabal init 初始化 cabal 之后)我尝试制作一个 cabal new-run它给出了一个错误:

$ 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
  |          ^^

使用 cabal run 也会出错。

我有 cabal 版本 2.4.0.0:

$ cabal --version
cabal-install version 2.4.0.0
compiled using version 2.4.0.1 of the Cabal library

和ghc版本8.6.5:

$ ghc --version
The Glorious Glasgow Haskell Compilation System, version 8.6.5

有人知道发生了什么事吗?

我知道如果我添加缩进就可以修复它:

main :: IO ()
main = do
    if False then undefined 
    else do
        let x = 5
        print x

但我想知道为什么它用 ghc 编译而不用 cabal new-run

您的代码需要语言扩展来解析:NondecreasingIndentation。此扩展的存在是为了避免嵌套 dos

的尴尬失控效果
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 允许嵌套的 do 块注册为嵌套,只要它缩进 包含块一样多,而不是 超过个容器。

根据 GHC manualNondecreasingIndentation 默认打开,但在 Haskell2010 模式下禁用(除非再次明确启用)。我找不到相应的 cabal 文档,但我们大概可以猜到它默认指定 Haskell2010.

您可以在源文件中指定要启用或禁用的扩展名,而不管外部选项如何,方法是添加编译指示

{-# LANGUAGE NondecreasingIndentation #-}

到文件的最顶部。