Been scratching my head for a day over this one.
I have a few functions in my code that look like this:
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 will load and run this interactively with no problems, and ghc will compile it happily.
Running this through cabal, however, gives me this:
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?
And whatever this -XDoAndIfThenElse option is, I can’t seem to find a trace of it anywhere in any documentation.
Why is cabal (or is this ghc by this point?) yelling at me for using semi-colons that IT put there in the first place? Or is using monadic expressions in if-then-else statements just a bad idea?
Note that cabal doesn’t complain about this at all:
case checkStatus status of
True -> monadTime >>= return . Just . processItPurely
_ -> return Nothing
…except this is ugly as hell and I’d never want to put this in my code.
Can anyone tell me what’s going on? Please and thanks in advance.
The “correct” way of indenting
if-expressions in ado-block is to indent theelseandthenlines further than theif, like this.This is because lines with the same amount of indentation in a
doblock are normally treated as separate statements.However, there is an extension called
DoAndIfThenElsewhich will allow you to write it the way you did. This extension was made standard in Haskell 2010, which is why GHC enables it by default.Cabal tends to require you to be more explicit about these things, so to use it in Cabal, you need to either mention it in your
.cabalfile or add{-# LANGUAGE DoAndIfThenElse #-}to the top of your module.