Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Haskell IO execution order

I've got the following code:

import Control.Monad (unless)
import System.IO (isEOF, hFlush, stdout)

main :: IO ()
main = unlessFinished $ do
        putStr "$ "
        hFlush stdout
        getLine >>= putStrLn
        main
    where
    unlessFinished action = isEOF >>= flip unless action

When I compile and run this code, it displays a cursor at the begining of the blank line and only after I hit [Enter] it outputs $ and whatever I'd written.

It would seem that getLine gets called before putStr "$ " even though IO monad guarantees that it's actions are called in the order they're sequenced in the code (or so I understand what is written here). So why it doesn't work correctly?

like image 822
Sventimir Avatar asked Nov 30 '15 22:11

Sventimir


Video Answer


1 Answers

Actually, the putStr and hFlush actions are being executed before the getLine action -- however, isEOF is being executed before either, and it doesn't return until it knows whether the input is EOF or not, that is, until you enter a line. You might consider moving the isEOF to right before the getLine, like this:

main :: IO ()
main = do
    putStr "$ "
    hFlush stdout
    unlessFinished $ do
        getLine >>= putStrLn
        main
    where
    unlessFinished action = isEOF >>= flip unless action
like image 97
Daniel Wagner Avatar answered Sep 26 '22 22:09

Daniel Wagner