Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I reset stdin in Haskell?

Tags:

io

stdin

haskell

I'm trying to write a urlview clone in Haskell. The program reads a message (piped via STDIN), extracts all URLs and asks the user to select one of them.

After reading the message, STDIN obviously reaches EOF. In Python, I reset STDIN like this

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

How would I achieve the same in Haskell?

like image 225
janeden Avatar asked Feb 09 '12 13:02

janeden


2 Answers

You cannot change the stdin handle in Haskell. In Python, the sys.stdin variable only points to a handle, so when you replace it with a new file handle, the old stdin handle still remains, but the sys.stdin variable now contains the file handle.

Since the System.IO.stdin handle is immutable in Haskell (as are so many other variables, or should I say values), you cannot do the same thing in Haskell.

What you can do is to open the /dev/tty file with a new handle, and use that handle to read from the terminal. You can use all of the same operations on any handle as you can on stdin. Simply import System.IO, and every time you would otherwise use foo ... to get some input, instead use hFoo handle .... For instance, to read a line from the terminal, use this code:

import System.IO

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

Don't forget to close your new handle with a call to hClose!

like image 182
dflemstr Avatar answered Oct 08 '22 14:10

dflemstr


As far as I know there is no way to "re-assign" the built-in stdin in Haskell, but you can otherwise open a new handle to /dev/tty. A direct translation of your Python code would be something like

import System.IO

main = do
    message <- getContents
    tty <- openFile "/dev/tty" ReadMode
    putStr "Which URL to open? "
    url <- hGetLine tty
    ...
like image 33
shang Avatar answered Oct 08 '22 13:10

shang