使用 Haskell2010 构建 cabal 文件时出现解析错误(可能是不正确的缩进...)

parse error (possibly incorrect indentation ...) when building a cabal file with Haskell2010

我刚刚在 Haskell 项目中遇到以下错误。 我为 Haskell 项目制作了一个 cabal 文件以正确安装它。当我用 ghc --make 构建我的二进制文件时,这个项目编译得很好但是当我用 cabal build 构建我的 cabal 文件时,我有以下错误:

src/Text/MarkIt/Verif.hs:12:3: error:
    parse error (possibly incorrect indentation or mismatched brackets)

我的文件开头是:

module Text.MarkIt.Verif where
import qualified Control.Monad.Trans.State.Strict as Tr
import Text.MarkIt.Types
import Data.List

class Verif a where
  summary :: a -> Tr.State StatDoc ()

instance Verif MarkIt where
  summary (MarkIt meta blocks) = do
  summary meta
  mapM_ summary blocks  -- This is the boring line

instance Verif Meta where
  summary meta = mapM_ summary (mAuthors meta)

我尝试用 ghc 重建我的可执行文件,它编译得很好。我检查了它们是否没有隐藏字符、制表、不正确的行尾……什么都没有! 我终于从我的 cabal 文件中删除了以下行:

default-language:    Haskell2010

然后,我的 cabal 文件构建并安装正常!

有人能解释一下为什么这个 cabal 选项会在我文件的这个精确位置导致这样的问题吗?

导致此问题的 Haskell 2010 语言规范有何不同?

默认情况下,GHC 处于 Haskell 98 模式,这可以从标准中放宽以下条件:

In Haskell 98 mode and by default (but not in Haskell 2010 mode), GHC is a little less strict about the layout rule when used in do expressions. Specifically, the restriction that “a nested context must be indented further to the right than the enclosing context” is relaxed to allow the nested context to be at the same level as the enclosing context, if the enclosing context is a do expression.

https://downloads.haskell.org/~ghc/latest/docs/html/users_guide/bugs.html#context-free-syntax

GHC 源代码中的评论进一步解释:

strictly speaking non-standard, but we always had this on implicitly before the option was added in 7.1, and turning it off breaks code, so we're keeping it on for backwards compatibility.

https://gitlab.haskell.org/ghc/ghc/blob/d0b45ac6984f245bce9de7ffcc7dad4a0046d344/compiler/main/DynFlags.hs#L2310

当您在您的 cabal 文件中启用 Haskell2010 模式时,该错误将得到修复,并且您的文件的语法将被拒绝。所以 do 块必须比封闭上下文缩进得更远,

    summary (MarkIt meta blocks) = do
      summary meta
      mapM_ summary blocks
--  ^ indented