I'm trying to comprehend haskell IO but this feature of stdin ultimately confuses me: When I try to use some function like getContents, for example in:
let main = do x<-getContents; putStrLn x
I get the following error:
hGetContents: illegal operation (handle is closed)
How I am supposed to do any IO with this? Is there some fix, or should I look up for another analogical IO function?
getContents == hGetContents stdin
. In fact hGetContents
marks its handle (semi-)closed and this means anything attempting to read from stdin ever again will fail.
Take a look at After using getContents in the Haskell User Guide
I'd suggest you to also investigate an alternative approach. There some inherent problems with getContents
and similar operations:
getContents
is a lazy IO
, which means (among other problems) that:
getContents
, the data are read using lazy IO
operations. This means that inside pure computations we can get IO
effects and errors.A safer alternative is to use another concept, called iteratees, conduits or pipes. The idea is that you describe your components as things that read some input data and/or write output and then combine them together. This allows you to write very robust and elegant code.
This does not reproduce in normal operation
If you try to use getContents
from within ghci
, as you seem to be doing, that's exactly what will happen when you use it the second time around. The first invocation will set the handle in the (semi)closed state, and all subsequent attempts to use it will fail.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With