【问题标题】:How do I reset stdin in Haskell?如何在 Haskell 中重置标准输入?
【发布时间】:2012-02-09 13:28:38
【问题描述】:

我正在尝试在 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 中实现同样的效果?

【问题讨论】:

    标签: haskell io stdin


    【解决方案1】:

    您不能在 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 来关闭您的新句柄!

    【讨论】:

      【解决方案2】:

      据我所知,没有办法在 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
          ...
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2022-11-10
        • 2012-05-11
        • 2010-09-21
        • 1970-01-01
        • 2011-01-27
        • 1970-01-01
        • 1970-01-01
        • 2020-06-11
        相关资源
        最近更新 更多