Haskell IO执行顺序
Haskell IO execution order
我有以下代码:
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
monad 保证它的动作是按照它们在代码中排序的顺序调用的(或者我是这样的理解写的内容 here)。那么为什么它不能正常工作?
实际上,putStr
和 hFlush
操作 是 在 getLine
操作之前执行的——但是,isEOF
在任何一个之前都在执行,并且它不会 return 直到它知道输入是否是 EOF
,也就是说,直到你输入一行。您可以考虑将 isEOF
移动到 getLine
之前,如下所示:
main :: IO ()
main = do
putStr "$ "
hFlush stdout
unlessFinished $ do
getLine >>= putStrLn
main
where
unlessFinished action = isEOF >>= flip unless action
我有以下代码:
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
monad 保证它的动作是按照它们在代码中排序的顺序调用的(或者我是这样的理解写的内容 here)。那么为什么它不能正常工作?
实际上,putStr
和 hFlush
操作 是 在 getLine
操作之前执行的——但是,isEOF
在任何一个之前都在执行,并且它不会 return 直到它知道输入是否是 EOF
,也就是说,直到你输入一行。您可以考虑将 isEOF
移动到 getLine
之前,如下所示:
main :: IO ()
main = do
putStr "$ "
hFlush stdout
unlessFinished $ do
getLine >>= putStrLn
main
where
unlessFinished action = isEOF >>= flip unless action