I'm encountering strange behaviour with IO, within compiled Haskell code. Here's what's going on:
-- MyScript.hs
main = do
putStr "Enter your name: "
a <- getLine
putStrLn (a ++ " - that's a nice name!")
I run this in GHCi by calling main
and it works as one would expect, first printing Enter your name:
and then doing whatever it's to do afterwards. However, when I compile it with GHC (With and without --make
), it first prompts for a line, and then prints everything at once, like this:
$ ./MyScript
Jimmy Johnson
Enter your name: Jimmy Johnson - That's a nice name!
To clarify, I want it to occur in the following sequence:
$ ./MyFixedScript
Enter your name: Jimmy Johnson
Jimmy Johnson - That's a nice name!
Could someone explain why this happens as it is, and how to sequence the IO the way that I would expect it to.
Note also that I've tried changing the first line of the do
statement to _ <- putStr "Enter your name: "
, but that still doesn't work.
The IO actions are happening in the correct order, the problem lies in how input and output pipes work. The string "Enter your name: "
is written to the output buffer by putStr
before the getLine
, but the buffer hasn't necessarily been flushed. Adding hFlush stdout
after the putStr
will flush the buffer.
import System.IO
-- MyScript.hs
main = do
putStr "Enter your name: "
hFlush stdout
a <- getLine
putStrLn (a ++ " - that's a nice name!")
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With