5

私は次のコードを持っています:

import Control.Monad (unless)
import System.IO (isEOF, hFlush, stdout)

main :: IO ()
main = unlessFinished $ do
        putStr "$ "
        hFlush stdout
        getLine >>= putStrLn
        main
    where
    unlessFinished action = isEOF >>= flip unless action

このコードをコンパイルして実行すると、空白行の先頭にカーソルが表示され、[Enter] を押した後にのみ出力$され、私が書いたものは何でも出力されます。

モナドは、コードでシーケンスされた順序でアクションが呼び出されることを保証しますgetLineが、前に呼び出されるように見えます (または、ここに書かれていることを理解しています)。では、なぜ正しく動作しないのでしょうか?putStr "$ "IO

4

1 に答える 1

10

実際には、putStrandhFlushアクションアクションの前に実行されていgetLineます -- ただし、isEOFはどちらかの前に実行されており、入力があるかどうかを知るまでEOF、つまり、行を入力するまで戻りません。次のようisEOFに、 を の直前に移動することを検討してください。getLine

main :: IO ()
main = do
    putStr "$ "
    hFlush stdout
    unlessFinished $ do
        getLine >>= putStrLn
        main
    where
    unlessFinished action = isEOF >>= flip unless action
于 2015-11-30T22:39:53.210 に答える