2012-02-09 27 views
8

Estoy tratando de escribir un clon de urlview en Haskell. El programa lee un mensaje (canalizado a través de STDIN), extrae todas las URL y le pide al usuario que seleccione una de ellas.¿Cómo reinicio Stdin en Haskell?

Después de leer el mensaje, STDIN obviamente llega a EOF. En Python, reinicié STDIN como este

message = sys.stdin.read() 
sys.stdin = open('/dev/tty') 
selected_index = raw_input('Which URL to open? ') 

¿Cómo conseguir lo mismo en Haskell?

Respuesta

7

Por lo que sé, no hay forma de "reasignar" el stdin incorporado en Haskell, pero de lo contrario puede abrir un nuevo identificador en /dev/tty. Una traducción directa de su código Python sería algo así como

import System.IO 

main = do 
    message <- getContents 
    tty <- openFile "/dev/tty" ReadMode 
    putStr "Which URL to open? " 
    url <- hGetLine tty 
    ... 
8

No se puede cambiar el mango stdin en Haskell. En Python, las variables sys.stdin sólo puntos a un mango, por lo que cuando se sustituya por un nuevo identificador de archivo, el viejo stdin mango sigue siendo, pero la variable de sys.stdin ahora contiene el identificador de archivo.

Dado que el mango System.IO.stdin es inmutable en Haskell (como muchas otras variables, o debería decir valores), no se puede hacer lo mismo en Haskell.

Lo que puede hacer es abrir el archivo /dev/tty con un nuevo identificador , y usar ese asa para leer desde el terminal. Puede usar todas las mismas operaciones en cualquier manejador que pueda en stdin. Simplemente importe System.IO, y cada vez que use foo ... para obtener alguna entrada, en su lugar use hFoo handle .... Por ejemplo, para leer una línea desde el terminal, utilice este código:

import System.IO 

-- ... 
newstdin <- openFile "/dev/tty" ReadMode 
-- Instead of normal getLine; just prepend "h" and pass the handle 
line <- hGetLine newstdin 

No se olvide de cerrar su nuevo mango con una llamada a hClose!