我正在尝试在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中实现同样的目标?
答案 0 :(得分:8)
您无法更改Haskell中的stdin
句柄。在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
来关闭新句柄!
答案 1 :(得分:7)
据我所知,无法在Haskell中“重新分配”内置stdin
,但您可以打开/dev/tty
的新句柄。 Python代码的直接翻译类似于
import System.IO
main = do
message <- getContents
tty <- openFile "/dev/tty" ReadMode
putStr "Which URL to open? "
url <- hGetLine tty
...