GHCi和编译的代码似乎表现不同

Dou*_*ore 8 io haskell

我有一个非常奇怪的问题.与在ghci中运行相比,以下代码在编译时给出不同的结果,

main = do
  putStr "Please enter your name: "
  name <- getLine
  putStr ("Hello, " ++ name ++ ", how are you?")
Run Code Online (Sandbox Code Playgroud)

当它在ghci中运行时,它就像人们期望的那样,

Please enter your name: dglmoore
Hello, dglmoore, how are you?
Run Code Online (Sandbox Code Playgroud)

但是,当我将代码编译为可执行文件时,它需要在生成任何输出之前提供输入,所以我最终得到了这个,

dglmoore
Please enter your name: Hello, dglmoore, how are you?
Run Code Online (Sandbox Code Playgroud)

我以前见过类似的问题,但我似乎无法再找到它.

我在Haskell平台版本2012.2.0.0中使用ghc版本7.4.1.

任何人都知道为什么他们会给出不同的结果以及我如何让这两个版本做"正确"的事情?

sep*_*p2k 12

这是一个缓冲问题.通常IO是行缓冲的(即除非您显式刷新缓冲区,否则输出实际上不会显示在屏幕上,直到您打印新行或超过缓冲区大小).在ghci它不是,所以问题没有出现.

您可以使用hFlush stdout刷新标准输出,在打电话之前将输出打印到屏幕上getLine.

或者,您可以使用hSetBuffering NoBuffering完全禁用缓冲,无需使用hFlush.但这可能会对IO性能产生负面影响.

  • @DougMoore请注意,在大多数编程语言中都是行缓冲的终端输出 - 而不仅仅是Haskell(尽管在某些语言中,读取输入会自动导致输出被刷新,从而消除了此错误源). (3认同)