问题
I am getting this error in GHCI :
*** Exception: <stdin>: hGetLine: illegal operation (handle is semi-closed)
After running this code :
main = do
interact $ unlines . fmap proccess . take x . lines
readLn :: IO Int
And I am pretty sure the cause is take x
. Is there any better way to read only x lines of input using interact or is interact
just a solo player?
回答1:
What you're trying to do isn't possible with interact
. Behind the scenes interact
claims the entirety of stdin
for itself with hGetContents. This puts the handle into a “semi-closed” state, preventing you from attempting any further interaction with the handle besides closing it, as the entirety of its input has already been consumed (lazily).
Try reading a finite number of lines with—
import Control.Monad (replicateM)
getLines :: Int -> IO [String]
getLines n = replicateM n getLine
回答2:
Conceptually interact
consumes all of standard input. So it doesn't make any sense to call readLn
afterwards.
To only read a given number of lines, use something like:
import Control.Monad
main = do input <- replicateM 10 getLine
...
Here input
will be a list of (exactly) 10 Strings.
Things get more complicated if you want to allow for fewer lines or if you want to stop reading when you encounter a special condition.
来源:https://stackoverflow.com/questions/38776023/handle-is-semi-closed-error-in-haskell