Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why doesn't Haskell sequence these IO actions properly?

Tags:

haskell

A friend of mine asked me why was I learning Haskell. To demonstrate the power of Haskell I wrote a small program which displayed a list of prime numbers:

main = do
    putStr "Enter the number of prime numbers to display: "
    number <- fmap read getLine :: IO Int
    print . take number . filter isPrime $ [2..]

isPrime :: Integer -> Bool
isPrime n = not . any ((== 0) . mod n) $ [2..floor . sqrt . fromInteger $ n]

The program works as expected save a minor anomaly. It prints the prompt message after taking an input number from the user resulting in an output like:

12
Enter the number of prime numbers to display: [2,3,5,7,11,13,17,19,23,29,31,37]

Why is Haskell not sequencing the IO actions correctly? Where am I going wrong?

like image 608
Aadit M Shah Avatar asked Oct 22 '13 09:10

Aadit M Shah


2 Answers

This looks more like a buffering than a sequencing problem. What platform are you on? Have you tried forcing unbuffered output?

hSetBuffering stdout NoBuffering -- from System.IO
like image 111
JB. Avatar answered Oct 20 '22 12:10

JB.


stdin and stdout are two different files that needn't have any connection. Take e.g. the Unix shell command grep:

$ seq 1 100 | grep 2$ | less

seq 1 100 prints the numbers 1 to 100 to its stdout which is greps stdin (| connects the stdout of one command to the stdin of an other). grep then writes the lines that match the given regex to its stdout which is lesss stdin.

To force stdout (or any other file) to be written use hFlush from System.IO:

 hFlush stdout
like image 11
Adam Schmalhofer Avatar answered Oct 20 '22 13:10

Adam Schmalhofer