Skip to content

Instantly share code, notes, and snippets.

@hiroshi-maybe
Created December 29, 2012 11:07
Show Gist options
  • Save hiroshi-maybe/4406177 to your computer and use it in GitHub Desktop.
Save hiroshi-maybe/4406177 to your computer and use it in GitHub Desktop.
Refined todo.hs in Chap 9 of "Learn You a Haskell for Great Good!": http://learnyouahaskell.com/
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
dispatch "bump" = bump
dispatch command = doesntExist command
main = do
(command:argList)<-getArgs
dispatch command argList
doesntExist :: String->[String]->IO ()
doesntExist command _ =
putStrLn $ "The "++command++" command doesn't exist"
add :: [String]->IO ()
add [fileName, todoItem] = appendFile fileName (todoItem++"\n")
add _ = putStrLn "The add command takes exactly two arguments"
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
numberedTasks = zipWith (\n line->show n++" - "++line)
[0..] todoTasks
-- putStrLn "These are your TODO items:"
-- mapM_ putStrLn numberedTasks
let number = read numberString
-- newTodoItems = unlines $ delete (todoTasks !! number) todoTasks
removedTask = todoTasks !! number
(h,t) = splitAt number todoTasks
newTodoItems = unlines $ h++tail t
updateTodo fileName newTodoItems
bump :: [String]->IO ()
bump [fileName, numberString] = do
contents <- readFile fileName
let todoTasks = lines contents
number = read numberString
-- newTodoItems = unlines $ (todoTasks !! number):(delete (todoTasks !! number) todoTasks)
popTask = todoTasks !! number
(h,t) = splitAt number todoTasks
newTodoItems = unlines $ popTask:h++tail t
updateTodo fileName newTodoItems
updateTodo :: String->String->IO ()
updateTodo fileName todoItems = do
bracketOnError (openTempFile "." "_temp")
(\(tempName, tempHandle)->do
hClose tempHandle
removeFile tempName)
(\(tempName, tempHandle)->do
hPutStr tempHandle todoItems
hClose tempHandle
-- removeFile "todo.txt"
-- renameFile tempName "todo.txt"
removeFile fileName
renameFile tempName fileName)
@hiroshi-maybe
Copy link
Author

  • Fixed to handle duplicate elements correctly in function "remove"
  • Added bump function

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment