Haskell IO - hGetContents:非法操作(句柄关闭)

时间:2013-08-10 10:01:34

标签: haskell

我正在尝试理解haskell IO但是stdin的这个功能最终让我困惑: 当我尝试使用像getContents这样的函数时,例如:

let main = do x<-getContents; putStrLn x

我收到以下错误:

hGetContents: illegal operation (handle is closed)

我应该怎么做这个IO?是否有一些修复,或者我应该查找另一个模拟IO功能?

3 个答案:

答案 0 :(得分:8)

getContents == hGetContents stdin。实际上hGetContents标记其句柄(半)关闭,这意味着任何试图再次从stdin读取的东西都会失败。

查看After using getContents

中的Haskell User Guide

答案 1 :(得分:4)

This does not reproduce in normal operation

如果您尝试在getContents内使用ghci,正如您似乎正在做的那样,那就是第二次使用它时会发生的情况。第一次调用会将句柄设置为(半)关闭状态,所有后续使用它的尝试都将失败。

答案 2 :(得分:3)

我建议你也研究一种替代方法。 getContents和类似操作存在一些固有问题:

  1. 您可以拥有一个无效的句柄 - 一个已经关闭的句柄。这在大多数语言中很常见,但我们可以做得更好。理想情况下,我们希望确保一旦我们关闭手柄,我们就无法进一步使用它。
  2. getContentslazy IO,表示(除其他问题外):
    • 我们很少或根本无法控制when (if) the handle is closed
    • 在我们处理getContents返回的字符串时,使用惰性IO操作读取数据。这意味着在纯计算中我们可以获得IO效果和错误。
  3. 更安全的替代方案是使用另一个概念,称为迭代,conduits或管道。我们的想法是将组件描述为读取某些输入数据和/或写入输出然后将它们组合在一起的东西。这使您可以编写非常强大而优雅的代码。