使用putStr和getLine时IO操作顺序错误

43

我有如下代码:

main = do
    putStr "Test input : "
    content <- getLine
    putStrLn content

当我运行它(runhaskell)或编译它(ghc 6.10.4)时,结果如下:

asd
Test input : asd
为什么会在asd之后打印Test input: asd
在来自http://learnyouahaskell.com/的代码示例中,使用putStr时,getLine的输出与我的不同。当我使用putStrLn时,程序按预期工作(先打印,然后提示,再打印)。
这是ghc中的一个错误还是它应该以这种方式工作?
1个回答

57
这是因为GHCi禁用了缓冲,而使用GHC编译的程序默认启用行缓冲。您可以通过运行以下命令来查看:
import System.IO
main = print =<< hGetBuffering stdout
在ghci中,你会看到NoBuffering,而用runghc则会出现LineBuffering。由于换行符直到用户输入后才打印出来,提示也是一样的情况。

通过在提示后添加hFlush stdout(或使用hSetBuffering stdout NoBuffering禁用缓冲,但这可能是不好的)来解决这个问题。


3
你可能需要使用import System.IO而不是import IO - Kamil Szot
@KamilSzot:在使用System.IO时,我遇到了相同的症状。 - René Jahn
有必要将其缓冲吗? - TankorSmash

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接