我对同一个函数有三个定义:
prompt :: String -> IO String
prompt = (getLine <*) . (hFlush stdout <*) . putStrLn
prompt' :: String -> IO String
prompt' str = do
putStrLn str
hFlush stdout
getLine
prompt'' :: String -> IO String
prompt'' str = putStrLn str >> hFlush stdout >> getLine
prompt'
和prompt''
都在运行getLine
之前刷新标准输出,但没有prompt
。为什么会这样?
答案 0 :(得分:7)
因为这不是您要的。自
prompt = (getLine <*) . (hFlush stdout <*) . putStrLn
我们可以添加一个参数来查看得到的结果:
prompt str = ((getLine <*) . (hFlush stdout <*) . putStrLn) str
= getLine <* hFlush stdout <* putStrLn str
这要求按顺序运行动作getLine
,hFlush stdout
和putStrLn str
。 (然后,该操作序列的结果值就是getLine
刚开始时的结果值。)您需要这样做:
prompt str = putStrLn str *> hFlush stdout *> getLine
或:
prompt = (*> getLine) . (*> hFlush stdout) . putStrLn
(实际上,大多数情况下默认的缓冲是行缓冲或更少,并且您正在调用putStrLn
而不是putStr
,因此这些解决方案中的 none 都不需要致电hFlush stdout
!)