来自 Windows,我最近通过 bash (ghc 7.10) 安装了名为 Peppermint 和 Haskell-Platform 的 Linux 发行版,但是 ghci 中的 ghci stdin 一定有问题,因为:
交互 $ 取 0
抛出错误但是
互动 $ take 1
没有。
此外,如果我在写入 stdin 时使用 backspace
、arrows
或任何其他控制按钮,它会输入 char 符号。例如退格键将^?
输入ghci而不是删除最后输入的字符...
...@... ~ $ ghci GHCi, version 7.10.3: http://www.haskell.org/ghc/ :? for help Prelude> interact $ take 0 Prelude> <stdin>: hGetChar: illegal operation (handle is closed) ...@... ~ $ ghci GHCi, version 7.10.3: http://www.haskell.org/ghc/ :? for help Prelude> readLn :: IO String euoe^?^?^[[1;5C^[[D^[[B -- here I tried to delete 'euoe'
最佳答案
关于控制代码文字,这是因为您已经设法转义了通常会解释您的按键操作的所有行编辑器(readline、Haskeline)。
我不知道细节,但调用 GHCi 就像使用 bash --noediting
启动子 shell。这允许 GHCi 接收原始按键而不受 readline 库的干扰。这样做是因为 Haskeline(GHCi 使用它代替 readline)可以更轻松地配置可用功能的制表符完成之类的东西(您知道 GHCi 提供制表符完成,对吧?)。
然后从 GHCi 调用 getLine
有效地穿过陷阱门并通过直接进入 stdin 来完全避开 Haskeline。毕竟,只有一个标准输入。您现在正在直接向无缓冲终端输入。
回到您的第一个问题,只有一个标准输入也是 GHCi 在打印 Prelude>
提示后立即崩溃的原因。 interact
(在幕后使用 hGetContents
)声称它将处理所有将通过句柄 (stdin) 传入的输入作为一个大的惰性 String
。实际上,interact
尚未声明要处理的句柄上没有剩余输入,因此句柄会立即进入“半关闭”状态。它没有关闭(仍然可能有更多的输入将被读取为惰性 String
interact
获取的一部分!)但它已关闭任何新来者,否则输入将被重复(interact
和 handle 的新读者,例如 getLine
将获得相同的行!)。
回到 GHCi,在使用 interact
之后,stdout 仍然可以正常打印提示,然后 GHCi 依靠 Haskeline 返回一行进行处理。 Haskeline(作为行编辑器)调用阻塞 getChar
(iirc) 来向行添加字符或执行一些行编辑命令并死掉,因为它正在寻址半封闭句柄。因此,一个较弱的生物确实倒下了,而生命的巨轮继续滚动。
关于linux - 在 Linux 上的 ghci 中读取标准输入被破坏,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38816153/