Haskell do语法和I/O

Haskell do语法和I/O,haskell,ghc,ghci,Haskell,Ghc,Ghci,我在Haskell玩一个简单的程序: hello :: String -> String hello s = "Hello, " ++ (trim s) ++ "!\n" trim :: String -> String trim [] = [] trim s = head $ words s main :: IO() main = do putStr "\nPlease enter your name: " name <- getLine

我在Haskell玩一个简单的程序:

hello :: String -> String
hello s = "Hello, " ++ (trim s) ++ "!\n"

trim :: String -> String
trim [] = []
trim s = head $ words s

main :: IO()
main = do putStr "\nPlease enter your name: "
          name <- getLine
          hstring <- return $ hello name
          putStr hstring
当我将程序加载到ghci中时,它会按预期工作。但是,当我使用

ghc -o hello.exe hello.hs
它启动并等待输入,然后同时打印两个提示:

John Doe
Please enter your name: Hello, John!
为什么交互环境和编译器之间的行为不同,如何让编译器做我想做的事情


提前感谢您的帮助

这是一个常见问题。您的线路正在缓冲。使用:

import System.IO

main = do
    hSetBuffering stdout NoBuffering
    ...
另外,您的代码有点。。。独一无二。例如,你说:

hstring <- return $ hello name
putStr hstring
或者只是:

putStr $ hello name

当禁用所有缓冲过度时,明智地使用
hFlush stdout
是一个很好的选择。我仍然不明白问题中发布的代码为什么会导致错误的输出。do符号中的动作不应该按顺序排列吗?@is7s,我也是这么想的。@is7s:是的,但正如TomMD所说,输出是行缓冲的。因此,如果执行
putStr“bla”>>someOtherAction
putStr“bla”
确实会首先执行,但在刷新输出流之前,它将不可见,因此它看起来好像是
putStr
在发生这种情况之前没有执行。@is7s
hSetBuffering
hFlush
是解决方案。关于
hello name
的讨论只是一个风格点,在功能上等同于astay13已经拥有的功能。
main=putStr“请输入您的名字:”>>getLine>>=putStr。你好
-只是为了好玩。
let hstring = hello name
putStr hstring
putStr $ hello name