Created
February 18, 2012 18:21
-
-
Save osa1/1860526 to your computer and use it in GitHub Desktop.
I wrote 103 lines of imperative code in Haskell :P
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
module Main where | |
{- | |
I wrote this to get a bettern understanding of Haskell way of doing | |
side effects, which turns out, is not much fun :) | |
-} | |
import Todo | |
import System.Environment | |
import System.FilePath | |
import System.IO | |
import Data.List | |
import Data.Time | |
{- | |
Beware! Most complex syntax since C++ ahead ! | |
-} | |
main = do | |
handle <- openFile "todos.txt" ReadMode | |
todos <- readTodos handle [] | |
hClose handle | |
app todos | |
menu = [ ("Add Todo", addTodo) | |
, ("Remove Todo", removeTodo) | |
, ("Save", writeTodos) | |
] | |
app :: [Todo] -> IO () | |
app todos = do | |
showTodos todos | |
showMenu | |
input <- getLine | |
let selection = read input :: Int | |
newTodos <- snd (menu !! selection) todos | |
app newTodos | |
showTodos todos = do | |
let todoStrs = map show todos | |
mapM_ (\todo -> putStr $ todo ++ | |
concat (take 50 (repeat "-")) ++ "\n") todoStrs | |
today :: IO Day | |
today = do | |
t <- getZonedTime | |
return (localDay $ zonedTimeToLocalTime t) | |
hGetNonEmptyLine :: Handle -> IO String | |
hGetNonEmptyLine handle = do | |
line <- hGetLine handle | |
if line == "" | |
then hGetNonEmptyLine handle | |
else return (line) | |
readTodo :: Handle -> IO Todo | |
readTodo handle = do | |
desc <- hGetNonEmptyLine handle | |
priorityS <- hGetNonEmptyLine handle | |
deadlineS <- hGetNonEmptyLine handle | |
let priority = read priorityS :: Int | |
let deadline = read deadlineS :: Day | |
return (Todo desc priority deadline) | |
readTodos :: Handle -> [Todo] -> IO [Todo] | |
readTodos handle todos = do | |
eofp <- hIsEOF handle | |
if eofp | |
then return todos | |
else do nextTodo <- readTodo handle | |
readTodos handle (insert nextTodo todos) | |
writeTodos :: [Todo] -> IO [Todo] | |
writeTodos todos = do | |
handle <- openFile "todos.txt" WriteMode | |
mapM_ (\todo -> let str = desc todo ++ "\n" ++ show (priority todo) | |
++ "\n" ++ show (deadline todo) | |
in hPutStrLn handle str) todos | |
hClose handle | |
return todos | |
removeTodo :: [Todo] -> IO [Todo] | |
removeTodo todos = do | |
idx <- readId | |
return $ removeIdx idx todos | |
addTodo :: [Todo] -> IO [Todo] | |
addTodo todos = do | |
putStr "Todo description: " | |
descS <- getLine | |
putStr "Todo priority: " | |
priS <- getLine | |
let priority = read priS :: Int | |
putStr "Todo deadline(YYYY-MM-DD): " | |
dayS <- getLine | |
let day = read dayS :: Day | |
return $ insert (Todo descS priority day) todos | |
removeIdx n lst = (take n lst) ++ (drop (n+1) lst) | |
readId :: IO Int | |
readId = do | |
putStr "Enter index of Todo item: " | |
input <- getLine | |
let id = read input :: Int | |
return id | |
showMenu = do | |
mapM_ (\menuItem -> do putStrLn $ "[" ++ (show $ fst menuItem) ++ "] " | |
++ (fst $ snd menuItem)) (zip [0..] menu) | |
putStr "> " |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
module Todo where | |
import Data.Time | |
import Data.List | |
data Todo = Todo { desc :: String | |
, priority :: Int | |
, deadline :: Day } | |
instance Show Todo where | |
show (Todo desc pri dl) = "Description: " ++ desc ++ "\nPriority: " ++ show pri | |
++ "\nDeadline: " ++ show dl ++ "\n" | |
instance Eq Todo where | |
Todo _ _ p1 == Todo _ _ p2 = p1 == p2 | |
instance Ord Todo where | |
compare (Todo _ _ p1) (Todo _ _ p2) = compare p2 p1 |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment