我正在尝试在Haskell中编写urlview克隆.程序读取消息(通过STDIN管道传输),提取所有URL并要求用户选择其中一个.
阅读完消息后,STDIN显然达到了EOF.在Python中,我像这样重置STDIN
message = sys.stdin.read()
sys.stdin = open('/dev/tty')
selected_index = raw_input('Which URL to open? ')
我如何在Haskell中实现相同的目标?
您无法更改stdinHaskell中的句柄.在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!
据我所知,没有办法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
    ...