我想在哈斯克尔的一个小实验,想知道是否有可能利用懒惰来处理IO。我想编写一个函数,它接受一个String(一个Chars列表),并产生一个字符串,懒洋洋地。然后,我希望能够懒惰地从IO中缓慢地提供它的字符,因此每个字符都会在可用时立即进行处理,并且会在需要的字符可用时生成输出。但是,我不太确定是否/如何从IO单元内的输入中生成一个懒惰列表。Haskell中的“惰性IO”?
回答
Haskell中的常规字符串IO很懒。所以你的例子应该是开箱即用。
下面是一个例子,使用“交互”功能,它适用的功能字符的懒惰流:
interact :: (String -> String) -> IO()
让我们从输入流中过滤出字母e,懒惰地(即,运行在不断的空间):
main = interact $ filter (/= 'e')
你也可以,如果你喜欢用getContents和putStr。他们都很懒。
运行它从字典中筛选字母“E”:
$ ghc -O2 --make A.hs
$ ./A +RTS -s < /usr/share/dict/words
...
2 MB total memory in use (0 MB lost due to fragmentation)
...
,所以我们看到它在一个恒定2M足迹跑了。
你也可以在命令行看到这个效果。在shell/Terminal /运行Don的'A'程序,无论您的操作系统使用什么,并直接输入文本。假设它是行缓冲的,当你在每行之后按回车时,即使程序看起来只是对“过滤器”进行一次“调用”,你仍会立即看到过滤后的文本。 – Nefrubyr 2010-02-19 11:49:10
unsafeInterleaveIO :: IO a -> IO a
unsafeInterleaveIO
阿洛斯IO
计算被推迟懒洋洋地。当通过IO a
类型的值时,IO
将仅在要求值a
时执行。这用于实现惰性文件读取,请参阅System.IO.hGetContents
。
例如,main = getContents >>= return . map Data.Char.toUpper >>= putStr
是懒惰的;当你向标准输入提供字符时,你会在标准输出中获得字符。
(这是一样的书写main = interact $ map Data.Char.toUpper
,为行踪诡秘的回答。)
做懒IO的最简单的方法涉及的功能,如interact
,readFile
,hGetContents
,而这样,作为穿上说;在书中Real World Haskell中有更多关于这些的讨论,您可能会觉得有用。如果内存服务于我,所有这些功能最终都会使用ephemient提到的unsafeInterleaveIO
来实现,所以您也可以按照自己的意愿构建自己的函数。
另一方面,请注意unsafeInterleaveIO
正如它在锡罐上所说的那样:不安全的IO可能是明智的。使用它 - 或基于它的功能 - breaks purity and referential transparency。这允许显然是纯粹的功能(即,不返回IO
动作)在评估时影响外部世界,从相同的参数产生不同的结果,以及所有其他不愉快的事情。在实践中,使用unsafeInterleaveIO
的最明智的方式不会造成问题,而简单的错误通常会导致明显且容易诊断的错误,但是您失去了一些很好的保证。
当然有其他选择;你可以在Hackage上找到提供受限制的,safer lazy IO或conceptually different approaches的各种图书馆。但是,鉴于问题在实际使用中很少出现,我认为大多数人倾向于坚持内置的,技术上不安全的功能。
- 1. Haskell:隐藏IO惰性故障
- 2. 困惑:Haskell IO懒惰
- 3. Haskell:原子IO包装/懒惰?
- 4. Haskell惰性卸载
- 5. 强制对惰性IO进行评估
- 6. Haskell中的懒惰模式
- 7. Haskell中IO的映射
- 8. 与haskell中的IO映射?
- 9. Haskell中的IO问题
- 10. Haskell中的IO不可见
- 11. Haskell惰性打开和关闭文件
- 12. Haskell的IO递归
- 13. Haskell的IO例如
- 14. Haskell monadic IO
- 15. Haskell ReplicateM IO
- 16. Haskell基本IO
- 17. Haskell,IO,monads,quickcheck
- 18. IO monad中的懒惰计算
- 19. 懒惰的本质。 Haskell
- 20. 观察Haskell的懒惰
- 21. Haskell IO与数字
- 22. 递归IO在Haskell
- 23. haskell io流内存
- 24. Haskell比较IO UTCTime
- 25. haskell网络io hgetline
- 26. 惰性IO +并行性:将图像转换为灰度
- 27. Haskell中的懒惰前向参考
- 28. 帮助Haskell的IO输入
- 29. Haskell内部的IO实现
- 30. Haskell的函数定义IO
请澄清:你需要一个接受一个字符串和“产生”一个字符串---“产生”=“返回”,“输出到文件句柄”的函数,或者是什么?然后你想“懒惰地从IO中提取字符”---这是什么意思? – dave4420 2010-02-18 16:42:25