Edw*_*ard 8 io haskell lazy-evaluation
我正在尝试在haskell做一个小实验,想知道是否有可能利用懒惰来处理IO.我想编写一个函数,它接受一个字符串(一个字符列表)并生成一个字符串,懒洋洋地.我希望能够懒洋洋地从IO中提取字符,因此每个字符一旦可用就会被处理,并且输出将在必要的字符可用时生成.但是,我不太确定是否/如何从IO monad中的输入生成一个懒惰的字符列表.
Don*_*art 14
Haskell中的常规字符串IO是懒惰的.所以你的例子应该开箱即用.
这是一个例子,使用'interact'函数,它将一个函数应用于一个惰性字符流:
interact :: (String -> String) -> IO ()
Run Code Online (Sandbox Code Playgroud)
让我们从输入流中过滤掉字母'e',懒洋洋地(即在恒定空间中运行):
main = interact $ filter (/= 'e')
Run Code Online (Sandbox Code Playgroud)
如果您愿意,也可以使用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)
...
Run Code Online (Sandbox Code Playgroud)
所以我们看到它以2M的恒定速度运行.
做懒惰IO的最简单的方法涉及的功能,如interact,readFile,hGetContents,并且这样的,如穿上说; 在Real World Haskell一书中对这些内容进行了更广泛的讨论,你可能会发现它们很有用.如果记忆为我服务,所有这些功能最终都会使用unsafeInterleaveIO那个流行的提及来实现,所以你也可以按照你想要的方式构建自己的功能.
另一方面,值得注意的unsafeInterleaveIO是,这正是它在锡上所说的:不安全的IO.使用它 - 或基于它的功能 - 打破纯度和参考透明度.这允许显然纯粹的函数(即,不返回IO动作)在评估时影响外部世界,从相同的参数产生不同的结果,以及所有其他不愉快的事物.在实践中,最明智的使用unsafeInterleaveIO方式不会导致问题,简单的错误通常会导致明显且容易诊断的错误,但是你已经失去了一些很好的保证.
当然还有其他选择; 你可以在Hackage上找到各种各样的库,提供有限的,更安全的懒惰IO或概念上不同的方法.然而,鉴于实际使用中很少出现问题,我认为大多数人都倾向于坚持使用内置的,技术上不安全的功能.
| 归档时间: |
|
| 查看次数: |
2137 次 |
| 最近记录: |