为这个问题挠了一天。
我的代码中有一些函数如下所示:
function :: IO (Maybe Whatever)
function = do
monadFun
yaySomeIO
status <- maybeItWillFail
if checkStatus status -- Did we succeed?
then monadTime >>= return . Just . processItPurely
else return Nothing
ghci 将毫无问题地以交互方式加载和运行它,ghc 将愉快地编译它。
然而,通过 cabal 运行它给了我这个:
myProgram.hs:94:16:
Unexpected semi-colons in conditional:
if checkStatus status; then monadTime >>= return . Just . processItPurely; else return Nothing
Perhaps you meant to use -XDoAndIfThenElse?
无论如何
-XDoAndIfThenElse
选项是,我似乎无法在任何文档的任何地方找到它的踪迹。为什么 cabal(或者此时是 ghc?)因为我使用 IT 首先放在那里的分号而对我大喊大叫?或者在 if-then-else 语句中使用单子(monad)表达式只是一个坏主意?
请注意, cabal 根本不会提示这一点:
case checkStatus status of
True -> monadTime >>= return . Just . processItPurely
_ -> return Nothing
...除了这很难看,我永远不想把它放在我的代码中。
谁能告诉我发生了什么事?请提前致谢。
最佳答案
缩进的“正确”方式if
-do
中的表达式-block 是缩进 else
和 then
比 if
更远的行, 像这样。
function = do
monadFun
yaySomeIO
status <- maybeItWillFail
if checkStatus status -- Did we succeed?
then monadTime >>= return . Just . processItPurely
else return Nothing
这是因为
do
中缩进量相同的行 block 通常被视为单独的语句。但是,有一个名为
DoAndIfThenElse
的扩展名。这将允许您按照自己的方式编写它。此扩展在 Haskell 2010 中成为标准,这就是 GHC 默认启用它的原因。Cabal 倾向于要求您对这些事情更加明确,因此要在 Cabal 中使用它,您需要在
.cabal
中提及它。文件或添加 {-# LANGUAGE DoAndIfThenElse #-}
到模块的顶部。
关于haskell - 条件句中的一元表达式 - GHC 编译,cabal 拒绝,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10867300/