Неправильный порядок действий ввода-вывода с использованием putStr и getLine - PullRequest
38 голосов
/ 23 марта 2010

У меня есть следующий код:

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

Когда я запускаю его (с runhaskell) или компилирую (ghc 6.10.4), результат выглядит так:

asd
Test input : asd

Почему Test input : asd печатается после asd?

В примере кода на http://learnyouahaskell.com/,, который использует putStr, представленный вывод getLine отличается от моего. Когда я использую putStrLn, программа работает должным образом (печать, затем подсказка и печать).

Это ошибка в ghc, или она должна работать?

1 Ответ

52 голосов
/ 23 марта 2010

Это потому, что ghci отключает буферизацию, в то время как программа, скомпилированная с ghc, имеет буферизацию строки по умолчанию. Вы можете увидеть это, запустив это:

import System.IO
main = print =<< hGetBuffering stdout

В ghci вы видите NoBuffering, тогда как с runghc вы получаете LineBuffering. Поскольку символ новой строки не печатается до тех пор, пока после пользовательского ввода, приглашение также не выводится.

Исправьте это, добавив hFlush stdout после вашего приглашения (или отключите буферизацию с помощью hSetBuffering stdout NoBuffering, но это, вероятно, плохо).

...