Reputation: 2056
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?
Upvotes: 4
Views: 395
Reputation: 152837
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
Upvotes: 10