Handle is semi-closed error in Haskell?

孤街浪徒 提交于 2019-12-23 12:29:38

问题


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

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!