gpt4 book ai didi

haskell - hGetContents 太懒了

转载 作者:行者123 更新时间:2023-12-03 23:28:45 27 4
gpt4 key购买 nike

我有以下代码片段,我将其传递给 withFile :

text <- hGetContents hand 
let code = parseCode text
return code

这里的手是一个有效的文件句柄,用 ReadMode 打开和 parseCode是我自己的函数,它读取输入并返回一个 Maybe。实际上,该函数失败并返回 Nothing。相反,如果我写:
text <- hGetContents hand 
putStrLn text
let code = parseCode text
return code

我得到了一个正义,因为我应该。

如果我这样做 openFilehClose我自己,我也有同样的问题。为什么会这样?我怎样才能干净地解决它?

谢谢

最佳答案

hGetContents不是太懒,只是需要与其他东西适本地组合,才能达到预期的效果。改名exposeContentsToEvaluationAsNeededForTheRestOfTheAction 或许情况会更清楚或只是 listen .
withFile打开文件,做某事(或什么都不做,随你所愿——在任何情况下,这正是你对它的要求),然后关闭文件。

揭示“懒惰 IO”的所有奥秘是不够的,但现在考虑一下括号中的这种差异

 good file operation = withFile file ReadMode (hGetContents >=> operation >=> print)
bad file operation = (withFile file ReadMode hGetContents) >>= operation >>= print

-- *Main> good "lazyio.hs" (return . length)
-- 503
-- *Main> bad "lazyio.hs" (return . length)
-- 0

粗略地说, bad在文件执行任何操作之前打开和关闭文件; good在打开和关闭文件之间做所有事情。您的第一个操作类似于 bad . withFile应该管理您想要完成的所有操作,这取决于句柄。

如果您使用 String,则不需要严格执行器,小文件等,只是一个想法组合是如何工作的。再次,在 bad在关闭文件之前我所做的只是 exposeContentsToEvaluationAsNeededForTheRestOfTheAction .在 good我撰写 exposeContentsToEvaluationAsNeededForTheRestOfTheAction考虑到其余的操作,然后关闭文件。

熟悉的 length + seq Patrick提到的技巧,或 length + evaluate值得知道;您对 putStrLn txt 的第二次操作是一个变种。但是重组更好,除非惰性 IO 不适合您的情况。
$ time ./bad
bad: Prelude.last: empty list
-- no, lots of Chars there
real 0m0.087s

$ time ./good
'\n' -- right
()
real 0m15.977s

$ time ./seqing
Killed -- hopeless, attempting to represent the file contents
real 1m54.065s -- in memory as a linked list, before finding out the last char

不言而喻,ByteString 和 Text 值得了解,但考虑到评估的重组更好,因为即使有了它们,你也经常需要 Lazy 变体,然后它们涉及到掌握组合形式之间的相同区别。如果您正在处理此类 IO 不合适的(大量)类情况,请查看 enumerator , conduit和合作,一切都很棒。

关于haskell - hGetContents 太懒了,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10485740/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com