第9章 対話プログラム #5

では実際に解いてみよう。

9.9 練習問題

  1. アクション getLine に、削除キーで文字を消去できる機能を加えたアクション readLine :: IO String を定義せよ。
    ヒント:一文字削除するための制御文字は "\DEL"、一文字戻るための制御文字列は "\ESC[1D" である。

結局、terminalのバッファリングモードの関係で、VirtualBoxLinuxを動かした。 最近の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のほうがよかった気もする。