我试图理解haskell IO,但stdin的这个特性最终让我感到困惑:当我尝试使用getContents之类的函数时,例如:
let main = do x<-getContents; putStrLn x
我收到以下错误:
hGetContents: illegal operation (handle is closed)
我应该如何用这个做任何 IO?有什么解决方法,还是我应该寻找另一个类似的 IO 功能?
我试图理解haskell IO,但stdin的这个特性最终让我感到困惑:当我尝试使用getContents之类的函数时,例如:
let main = do x<-getContents; putStrLn x
我收到以下错误:
hGetContents: illegal operation (handle is closed)
我应该如何用这个做任何 IO?有什么解决方法,还是我应该寻找另一个类似的 IO 功能?
getContents == hGetContents stdin
. 实际上hGetContents
标志着它的句柄(半)关闭,这意味着任何试图再次从标准输入读取的东西都会失败。
我建议您也研究一种替代方法。有一些固有的问题getContents
和类似的操作:
getContents
是一个懒惰IO
的,这意味着(除其他问题外):
getContents
,使用惰性IO
操作读取数据。这意味着在纯计算中我们可以获得IO
效果和错误。更安全的替代方法是使用另一个概念,称为迭代器、管道或管道。这个想法是您将组件描述为读取一些输入数据和/或写入输出然后将它们组合在一起的东西。这使您可以编写非常健壮和优雅的代码。
如果您尝试使用getContents
from inside ghci
,就像您似乎正在做的那样,那正是您第二次使用它时会发生的事情。第一次调用会将句柄设置为(半)关闭状态,所有后续使用它的尝试都将失败。