Haskell IO执行命令

Haskell IO执行命令,haskell,io,order-of-execution,Haskell,Io,Order Of Execution,我有以下代码: import Control.Monad (unless) import System.IO (isEOF, hFlush, stdout) main :: IO () main = unlessFinished $ do putStr "$ " hFlush stdout getLine >>= putStrLn main where unlessFinished action = i

我有以下代码:

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
< >当我编译并运行这个代码时,它在空白行开始时显示一个游标,只有在命中[输入]之后,它才会输出<代码> $< /代码>以及我所写的任何东西。
看起来,
getLine
putStr“$”
之前被调用,即使
IO
monad保证它的动作是按照它们在代码中的顺序被调用的(或者我知道是怎么写的)。那么为什么它不能正常工作呢?

事实上,
putStr
hFlush
操作是在
getLine
操作之前执行的——但是,
isEOF
是在这两者之前执行的,并且直到它知道输入是否为
EOF
时才会返回,也就是说,直到您输入一行。您可以考虑在<代码> GETLION<代码>之前移动<代码> IS/OSCORE >,像这样:

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

顺便说一句,直到我自己试着运行代码,我才相信你。然后我在我的隔间里大声地说“哇啊…?!”。把你的问题提炼成这样一个好的、容易理解的、令人惊讶的形式真是太好了!非常感谢。我也很惊讶。事实上,我开始相信这毕竟不是Haskell的“错误”,而是我以前不知道的其他shell/terminal/OS陷阱。:)非常简单的解释!我已经在想我自己怎么就想不起来了。我发现,哈斯克尔对我来说仍然比我预想的有更多的陷阱。非常感谢。:)