プログラミング Haskell 第9章 対話プログラム 練習問題その1

またずいぶん間が開いてしまいました。第9章の練習問題を解いていきます。

  • 1. 問題文から察するに現在の文字数分 \DEL で文字を消すような方法が想定されているようでしたが、このエスケープシーケンスではわたしの端末でうまく文字を消してくれなかったので、'\r' で行頭に戻って空白でクリアする方法にしました。
redrawLine :: String -> IO ()
redrawLine s = do putChar '\r'
                  putStr (take ((length s)+2) (repeat ' '))
                  putChar '\r'
                  if s /= "" then putStr (init s)
                             else return ()


editLine :: String -> Char -> IO String
editLine buf '\n' = return buf
editLine "" '\DEL'  = do redrawLine ""
                         processLine ""
editLine buf '\DEL' = do redrawLine buf
                         processLine (init buf)
editLine buf c = processLine (buf ++ [c])

processLine :: String -> IO String
processLine buf = do ch <- getChar
                     editLine buf ch

readLine :: IO String
readLine = processLine ""
  • 2. エラー内容を表示する方法が面倒だったので電卓の下にエラー位置を表示するたけにしてしまいました。 追加した showerror 関数と変更した eval のみ記します。
showerror :: String -> IO ()
showerror xs = do writeat (2, 14) xs

eval :: String -> IO ()
eval xs = case parse expr xs of
            [(n, "")] -> calc (show n)
            [(_, rest)] -> do showerror rest
                              calc xs
            _ -> do beep
                    calc xs

時間がかかったわりに 2問しか解いてないです。 4. と 5. は仕様を考えるとか GUI ツールキットを使うなど大掛りになるのでパスしようと思います。 3, 6 はできれば解きたいです。次がいつになるかわかりませんけど。