我试图在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
答案 0 :(得分:1)
按Enter键时 - 按下任何其他键时 - 将其打印到屏幕上。您可以使用hSetEcho
关闭此行为:
main = do
hSetEcho stdin False
readEvalPrintLoop
但是,如果你这样做,你会发现这有一些附带损害:输入不再回显,但你输入的其他内容都没有,所以看起来你输入的一切都是看不见的!您可以通过手动实施修改后的echo策略来解决此问题。您需要做两件事:将输入流设置为带有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