當你按下enter鍵 - 當你按任何其他ke y - 它被打印到屏幕上。您可以關閉此行爲與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
@Bakuriu是的,它應該是你提到的輸入緩衝。請注意,此緩衝區不存在於Haskell應用程序中,而是存在於終端中(OS內核或終端仿真程序中)。默認情況下,終端響應每個鍵並像往常一樣移動光標,而不與應用程序進行任何交互。應用程序可以要求終端改變這種默認行爲,實際上ncurses是一種常見的方式。 – chi
@Bakuriu緩衝只與切線相關:這裏真正的問題是回聲。在我的回答中,我還*關閉緩衝區,但不阻止換行符的出現;相反,它允許所有其他內容一次出現,而不是緩衝區大小的塊! –
@Andrei如果你和我一樣,這個問題可能導致你想知道到底發生了什麼以及哪些行爲是可配置的。你可以在[The TTY demystified](http://www.linusakesson.net/programming/tty/)上閱讀更多關於它的內容,但我警告你:如果你只想完成任務,這將會是方式更多的信息比你想要的! –