Как мне сбросить стандартный ввод в Haskell? - PullRequest
8 голосов
/ 09 февраля 2012

Я пытаюсь написать клон urlview в Haskell.Программа читает сообщение (переданное через STDIN), извлекает все URL-адреса и просит пользователя выбрать один из них.

После прочтения сообщения STDIN, очевидно, достигает EOF.В Python я сбрасываю STDIN следующим образом

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

Как бы я достиг того же в Haskell?

Ответы [ 2 ]

8 голосов
/ 09 февраля 2012

Вы не можете изменить дескриптор stdin в Haskell. В Python переменная sys.stdin только указывает на дескриптор, поэтому, когда вы заменяете его новым дескриптором файла, старый stdin дескриптор остается, но sys.stdin переменная теперь содержит дескриптор файла.

Поскольку дескриптор System.IO.stdin является неизменяемым в Haskell (как и многие другие переменные, или я должен сказать значения), вы не можете сделать то же самое в Haskell.

Что вы можете сделать, это открыть файл /dev/tty с новым дескриптором и использовать этот дескриптор для чтения из терминала. Вы можете использовать все те же операции для любого дескриптора, что и для stdin. Просто импортируйте System.IO, и каждый раз, когда вы в противном случае использовали бы foo ..., чтобы получить какой-либо ввод, вместо этого используйте hFoo handle .... Например, чтобы прочитать строку из терминала, используйте этот код:

import System.IO

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

Не забудьте закрыть свой новый дескриптор, позвонив по номеру hClose!

7 голосов
/ 09 февраля 2012

Насколько я знаю, нет способа "переназначить" встроенный stdin в Haskell, но в противном случае вы можете открыть новый дескриптор для /dev/tty. Прямой перевод вашего кода Python будет выглядеть примерно так:

import System.IO

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