すごいHaskell楽しく学ぼうという本でHaskellを勉強しているのですが、ToDoリストをもっと楽しむという章に書いてあるコードをそのまま写経して実行してもエラーが出る(コンパイルエラーなので実行もできない)ので、正しいコードを載せておきます。
import System.Environment import System.Directory import System.IO import Data.List import Control.Exception dispatch :: String -> [String] -> IO() dispatch "add" = add dispatch "view" = view dispatch "remove" = remove main = do (command:argList) <- getArgs dispatch command argList add :: [String] -> IO() add [fileName, todoItem] = appendFile fileName (todoItem ++ "\n") view :: [String] -> IO() view [fileName] = do contents <- readFile fileName let todoTasks = lines contents numberedTasks = zipWith (\n line -> show n ++ " - " ++ line) [0..] todoTasks putStr $ unlines numberedTasks remove :: [String] -> IO() remove [fileName, numberString] = do contents <- readFile fileName let todoTasks = lines contents number = read numberString newTodoItems = unlines $ delete (todoTasks !! number) todoTasks bracketOnError (openTempFile "." "temp") (\(tempName, tempHandle) -> do hClose tempHandle removeFile tempName ) (\(tempName, tempHandle) -> do hPutStr tempHandle newTodoItems hClose tempHandle removeFile fileName renameFile tempName fileName )
書籍との差分
+ import Control.Exception
まず、bracketsOnErrorを使うのでControl.Exceptionモジュールが必要になります。
- numberedTasks = zipWith (\n line -> show n ++ " - " ++ line) [0..] todoTasks
numberedTasksはタスクの一覧を表示するために使うが、これはviewという関数で実装したので、removeには必要ありません。
実行例をみても、removeには何も表示されない
なので、remove関数内の表示系は全て削除します。
- putStrLn "There are your ToDo items:" - mapM_ putStrLn numberedTasks
以上です。
すごいH本のToDoリストを写経して動かない!となった方の参考になれば幸いです。
といっても、ここまで丁寧に読んでいれば分かることだと思います。
ちなみに、すごいH本は本当にいい入門書なので、これからHaskellを勉強したいという人にはぴったりです
- 作者: Miran Lipovača,田中英行,村主崇行
- 出版社/メーカー: オーム社
- 発売日: 2012/05/23
- メディア: 単行本(ソフトカバー)
- 購入: 25人 クリック: 580回
- この商品を含むブログ (73件) を見る
おまけ
練習課題として、受け取った番号のToDoを先頭に持ってくるbumpコマンドの実装例も載せておきます。
中身はほとんどremoveと同じです
bump :: [String] -> IO() bump [fileName, numberString] = do contents <- readFile fileName let todoTasks = lines contents number = read numberString bumpItem = todoTasks !! number newTodoItems = (unlines $ bumpItem : delete bumpItem todoTasks) bracketOnError (openTempFile "." "temp") (\(tempName, tempHandle) -> do hClose tempHandle removeFile tempName ) (\(tempName, tempHandle) -> do hPutStr tempHandle newTodoItems hClose tempHandle removeFile fileName renameFile tempName fileName )