Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Haskell Compiled IO-Action order and Flushing [duplicate]

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.

like image 905
AJF Avatar asked Dec 01 '22 15:12

AJF


1 Answers

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!")
like image 163
Cirdec Avatar answered Dec 18 '22 10:12

Cirdec