では実際に解いてみよう。
9.9 練習問題
- アクション
getLine
に、削除キーで文字を消去できる機能を加えたアクションreadLine :: IO String
を定義せよ。
ヒント:一文字削除するための制御文字は"\DEL"
、一文字戻るための制御文字列は"\ESC[1D"
である。
結局、terminalのバッファリングモードの関係で、VirtualBoxでLinuxを動かした。 最近のHugsにはgetChがないとのことでいろいろ面倒だったからGHCiを使うことにした。
module NineNineOne where import System.IO getCh :: IO Char getCh = do hSetEcho stdin False c <- getChar hSetEcho stdin True return c readLine :: IO String readLine = f "" where f xs = do c <- getCh handle xs c handle xs '\n' = do putChar '\n' return xs handle [] '\DEL' = f "" handle xs '\DEL' = do putStr "\ESC[1D \ESC[1D" f (init xs) handle xs c = do putChar c f (xs ++ [c])
書いた後で考えると、init xs
とかxs ++ [c]
が気持ち悪いな。逆順のリストにしておいて、Enterが押されたときにreturn reverse xs
のほうがよかった気もする。