我在编译的 Haskell 代码中遇到了奇怪的 IO 行为。这是发生的事情:
-- MyScript.hs
main = do
putStr "Enter your name: "
a <- getLine
putStrLn (a ++ " - that's a nice name!")
我通过调用 main
在 GHCi 中运行此程序它的工作原理正如人们所期望的那样,首先打印 Enter your name:
然后做接下来该做的事。然而,当我用 GHC 编译它时(有或没有 --make
),它首先提示输入一行,然后然后立即打印所有内容,如下所示:
$ ./MyScript
Jimmy Johnson
Enter your name: Jimmy Johnson - That's a nice name!
为了澄清,我希望它按以下顺序发生:
$ ./MyFixedScript
Enter your name: Jimmy Johnson
Jimmy Johnson - That's a nice name!
有人可以解释一下为什么会发生这种情况,以及如何按照我期望的方式对 IO 进行排序。
另请注意,我尝试更改 do
的第一行致_ <- putStr "Enter your name: "
的声明,但这仍然不起作用。
最佳答案
IO 操作按照正确的顺序发生,问题在于输入和输出管道的工作方式。字符串 "Enter your name: "
在 getLine
之前被 putStr
写入输出缓冲区,但缓冲区不一定被刷新。在 putStr
之后添加 hFlush stdout
将刷新缓冲区。
import System.IO
-- MyScript.hs
main = do
putStr "Enter your name: "
hFlush stdout
a <- getLine
putStrLn (a ++ " - that's a nice name!")
关于Haskell 编译 IO-Action 顺序和刷新,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27324354/