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] 后它才会输出$我写的任何内容。

即使monad 保证按照它们在代码中的排序顺序调用它的动作(或者我理解这里写的内容),它似乎也会getLine被调用。那么为什么它不能正常工作呢?putStr "$ "IO

4

1 回答 1

10

实际上,putStrandhFlush动作在 action 之前执行的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 回答