Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/haskell/8.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Haskell中的句柄是半闭错误?_Haskell_Io_Handle - Fatal编程技术网

Haskell中的句柄是半闭错误?

Haskell中的句柄是半闭错误?,haskell,io,handle,Haskell,Io,Handle,我在GHCI中遇到以下错误: ***异常::hGetLine:非法操作(句柄半关闭) 运行此代码后: main = do interact $ unlines . fmap proccess . take x . lines readLn :: IO Int 我很确定原因是,take x。有没有更好的方法可以使用interact只读取x行输入,或者interact只是一个单独的玩家?使用interact你不可能做到的。幕后interactive声称自己拥有stdin的全部功能。

我在GHCI中遇到以下错误:

***异常::hGetLine:非法操作(句柄半关闭)

运行此代码后:

main = do
    interact $ unlines . fmap proccess . take x . lines
    readLn :: IO Int

我很确定原因是,
take x
。有没有更好的方法可以使用interact只读取x行输入,或者
interact
只是一个单独的玩家?

使用
interact
你不可能做到的。幕后
interactive
声称自己拥有
stdin
的全部功能。这会将句柄置于“半关闭”状态,防止您尝试与句柄进行任何进一步的交互(除了关闭它之外),因为它的全部输入已经被消耗(惰性地)

试着读有限数量的行-

import Control.Monad (replicateM)

getLines :: Int -> IO [String]
getLines n = replicateM n getLine

从概念上讲,
交互
消耗所有标准输入。因此,事后调用
readLn
没有任何意义

要仅读取给定数量的行,请使用以下方法:

import Control.Monad

main = do input <- replicateM 10 getLine
          ...
import-Control.Monad

main=do input
interact
将stdin置于半关闭状态。我假设您的函数在第一次正确运行,之后的每一次调用都失败了?关闭并重新打开GHCi,或者编译程序并执行它。确切地说,每次读取
stdin
之后都会失败。作为补充说明,除了关闭并重新打开GHCi之外,是否可以以其他方式重新打开stdin的关闭句柄?如@RowanBlush所示,
interact
或读取整个stdin的任何函数将
stdin
句柄置于半关闭状态。请记住,您的GHCI会话基本上是一个大的do块,编写
main=getContents>>getContents
同样无效。如果您想读取
n
行,只需使用
replicitem n getLine{readLn/whatever}
——使用读取所有stdin的函数之后将始终关闭stdin。您不能“重新打开”
stdin
——它只是一个隐藏的unix文件描述符。