haskell - 如何在Haskell中读取行而不转移到下一行?

标签 haskell io console readline

我尝试在 Haskell 中使用 readline,而不将光标转移到下一行。

例如,我编写了以下代码:

readEvalPrintLoop :: IO()
readEvalPrintLoop = do
    line <- getLine
    case line of
            "bye" -> return ()
            line   -> do putStrLn $ interpret line
                         readEvalPrintLoop

启动程序后:

> 1 2 + . <enter>
3

但我想找到获得关注的最简单方法:

> 1 2 + . <enter> 3

最佳答案

当您按 Enter 时(就像按任何其他键一样),它会打印到屏幕上。您可以使用 hSetEcho 关闭此行为:

main = do
    hSetEcho stdin False
    readEvalPrintLoop

但是,如果您这样做,您会发现这会带来一些附带损害:输入不再回显,但您输入的任何其他内容也不再回显,因此看起来您输入的所有内容都是不可见的!您可以通过手动实现修改后的回显策略来解决此问题。您需要做两件事:使用 hSetBuffering 将输入流设置为无缓冲模式。 (以便您立即收到输入,而不是在行尾)并打印收到的每个非输入字符。所以:

myGetLine :: IO String
myGetLine = do
    c <- getChar
    case c of
        '\n' -> return "" -- don't echo newlines
        _ -> do
            putChar c -- do echo everything else
            fmap (c:) myGetLine

readEvalPrintLoop :: IO()
readEvalPrintLoop = do
    line <- myGetLine -- getLine changed to myGetLine
    case line of
            "bye" -> return ()
            line   -> do putStrLn $ interpret line
                         readEvalPrintLoop

main = do
    hSetEcho stdin False
    hSetBuffering stdin NoBuffering
    readEvalPrintLoop

关于haskell - 如何在Haskell中读取行而不转移到下一行?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40717014/

相关文章:

Haskell 构造函数作为函数的变量

php - 带有转义字符的 Symfony 控制台输出

windows - Windows 上最好的 epoll/kqueue/select equvalient 是什么?

java - 下载没有缓冲区的文件: Nio is faster than io?

c - 如何在 C 中将一个 Int 分成两个字节?

python - 如何从Python控制台中删除最后几个字符?

ruby - 从 Ruby 控制台测试 Ruby on Rails OAuth API

haskell - GHC 导入功能或错误

haskell - 定义 Data.Void(Hackage 上的包 "void")的不必要类型杂耍?

haskell - 内存和重复 IO monad