2016-08-04 8 views
4

Я получаю эту ошибку в GHCI:Ручка полузамкнутая ошибка в Haskell?

*** Exception: <stdin>: hGetLine: illegal operation (handle is semi-closed)

После выполнения этого кода:

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

И я уверен, что причина take x. Есть ли лучший способ читать только x строки ввода с использованием взаимодействия или is interact просто сольный плеер?

+0

'взаимодействовать' ставит stdin в полузакрытое состояние. Я полагаю, что ваша функция работала правильно в первый раз, и каждый другой вызов после этого не удался? Либо закрыть, либо снова открыть GHCi, либо скомпилировать свою программу и выполнить ее. –

+0

Точно, каждое чтение 'stdin' потерпело неудачу после этого. –

+0

Как примечание, можно ли снова открыть закрытую ручку для stdin другим способом, но закрытие и повторное открытие ghci? –

ответ

8

То, что вы пытаетесь сделать, невозможно с interact. За кулисами interact претендует на полноту stdin для себя с hGetContents. Это ставит ручку в состояние “ полузакрытого состояния ”, что препятствует дальнейшему взаимодействию с ручкой, кроме ее закрытия, так как весь ее вход уже потреблен (лениво).

Попробуйте прочитать конечное число линий с —

import Control.Monad (replicateM) 

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

Концептуально interact потребляет все стандартного ввода. Поэтому нет смысла звонить по телефону readLn.

читать только заданное количество строк, использовать что-то вроде:

import Control.Monad 

main = do input <- replicateM 10 getLine 
      ... 

Здесь input будет список (точно) 10 строк.

Все становится более сложным, если вы хотите разрешить меньшее количество строк или если вы хотите прекратить чтение, когда вы сталкиваетесь с особым условием.