【问题标题】:Question about hFlush and lazy evaluation关于 hFlush 和惰性求值的问题
【发布时间】:2019-10-28 20:19:15
【问题描述】:

我对同一个函数有三个定义:

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。这是为什么呢?

【问题讨论】:

    标签: haskell io monads lazy-evaluation pointfree


    【解决方案1】:

    因为那不是你想要的。自从

    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,因此没有这些解决方案实际上需要调用@ 987654331@!)

    【讨论】:

    • 这可能是把(&lt;*)flip (*&gt;) 混淆了,我当然犯了这个错误
    猜你喜欢
    • 1970-01-01
    • 2023-03-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-12-23
    • 1970-01-01
    • 1970-01-01
    • 2023-04-05
    相关资源
    最近更新 更多