关于Hasfell中的hFlush和惰性评估的问题

问题描述 投票:0回答:1

我具有相同功能的三个定义:

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之前刷新了stdout,但没有刷新prompt。为什么会这样?

haskell io monads lazy-evaluation
1个回答
6
投票

因为这不是您要的。由于

prompt = (getLine <*) . (hFlush stdout <*) . putStrLn

我们可以添加一个参数来查看得到的内容:

prompt str = ((getLine <*) . (hFlush stdout <*) . putStrLn) str
           = getLine <* hFlush stdout <* putStrLn str

这要求按顺序运行动作getLinehFlush stdoutputStrLn str。 (然后,该操作序列的结果值就是刚开始时的结果值getLine。)您想要的是:

prompt str = putStrLn str *> hFlush stdout *> getLine

或:

prompt = (*> getLine) . (*> hFlush stdout) . putStrLn

(实际上,在大多数情况下,默认缓冲是行缓冲或更少,并且您正在调用putStrLn,而不是putStr,因此这些解决方案的none实际上需要调用hFlush stdout!)

© www.soinside.com 2019 - 2024. All rights reserved.