Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Haskell - syntax in do blocks (using IO)

The compiler says

The last statement in a 'do' construct must be an expression:
rmax <- getInteger

when attempting to load a file containing the following snippets of code:

getInteger :: IO Integer
getInteger = readLn

main :: IO ()
main = do  
    putStrLn "specify upper limit of results"  
    rmax <- getInteger
    if rmax `notElem` mot
        then do putStrLn "run again and enter a multiple of 10"
        else do print pAllSorted

What does it (the compiler message) mean, and why does it occur here? (whereas it doesn't in:)

main = do   
    line <- getLine  
    if null line  
        then return ()  
        else do  
            putStrLn $ reverseWords line  
            main  

reverseWords :: String -> String  
reverseWords = unwords . map reverse . words  

(above example taken from http://learnyouahaskell.com/input-and-output)


1 Answers

Your indentation is probably messed up because of mixed tabs and spaces. In fact, there appears to be a stray tab in the code snippet in your question, which I'm assuming you pasted directly from your source file.

Most likely, GHC is interpreting the tabs differently from how your editor displays them, so it thinks the do block ends after the line in question.

As a rule of thumb, it's best to use only spaces in Haskell. The language defines very specific rules for interpreting tabs that most code editors don't agree with, but spaces are unambiguous and consistent.

like image 149
C. A. McCann Avatar answered Feb 25 '26 19:02

C. A. McCann



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!