2016-08-04 36 views
4

erhalte ich diesen Fehler in GHCI:Griff ist halbgeschlossener Fehler in Haskell?

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

diesen Code Nach dem Ausführen:

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

Und ich bin ziemlich sicher, dass die Ursache take x ist. Gibt es einen besseren Weg zu lesen nur x Zeilen der Eingabe mit Interaktion oder ist interact nur ein Solospieler?

+0

'interact' bringt stdin in einen halbgeschlossenen Zustand. Ich gehe davon aus, dass deine Funktion beim ersten Mal korrekt funktioniert hat und alle anderen Aufrufe danach fehlgeschlagen sind. Schließen oder öffnen Sie GHCi oder kompilieren Sie Ihr Programm und führen Sie es aus. –

+0

Genau, jedes Lesen von 'stdin' ist danach fehlgeschlagen. –

+0

Als eine Randnotiz, ist es möglich, geschlossener Handle zu stdin auf andere Weise wieder zu öffnen, aber ghci schließen und wieder öffnen? –

Antwort

8

Was Sie versuchen, ist mit interact nicht möglich. Hinter den Kulissen interact beansprucht die Gesamtheit von stdin für sich mit hGetContents. Dies versetzt den Handle in einen “ halbgeschlossenen ” -Status, der Sie davon abhält, weitere Interaktion mit dem Handle zu versuchen, außer es zu schließen, da die gesamte Eingabe bereits verbraucht wurde (träge).

Versuchen Sie, eine endliche Anzahl von Linien mit —

import Control.Monad (replicateM) 

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

Lesen Konzeptionell interactalle von Standardeingabe verbraucht. Es macht also keinen Sinn, danach readLn aufzurufen.

nur um eine bestimmte Anzahl von Zeilen zu lesen, verwenden Sie so etwas wie:

import Control.Monad 

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

Hier input wird eine Liste der (genau) 10 Strings sein.

Die Dinge werden komplizierter, wenn Sie weniger Zeilen berücksichtigen wollen oder wenn Sie aufhören wollen zu lesen, wenn Sie auf eine spezielle Bedingung stoßen.