import Data Char toUpper import Control Monad when import System IO hS

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
import Data.Char (toUpper)
import Control.Monad (when)
import System.IO (hSetBuffering, stdin, BufferMode(NoBuffering))
type Todo = String
type TodoList = [Todo]
numberList :: TodoList -> [String]
numberList = zipWith (\a b -> show a ++ ". " ++ b) [1..]
removeElem :: Int -> [a] -> [a]
removeElem i xs = let (as, bs) = splitAt i xs
in as ++ drop 1 bs
printStrs :: [String] -> IO ()
printStrs = mapM_ putStrLn
showTodoList :: TodoList -> String
showTodoList [] = "No entries"
showTodoList xs = unlines xs
addTodo :: TodoList -> Todo -> TodoList
addTodo = flip (:)
removeTodo :: TodoList -> Int -> TodoList
removeTodo = flip removeElem
prompt :: String -> IO String
prompt x = putStrLn x >> getLine
todoOp :: TodoList -> Action -> IO TodoList
todoOp xs View = putStr (showTodoList xs) >> return xs
todoOp xs Add = do
addTodo xs <$> prompt "What would you like to add?"
addTodo xs <$> getLine
todoOp [] Delete = putStrLn (showTodoList []) >> return []
todoOp xs Delete = do
printStrs xs
response <- prompt "Which line do you want to remove?"
removeTodo xs <$> readLn
return (removeTodo xs (read response))
todoOp xs _ = do
putStrLn "Operation not supported"
return xs
data Action = Add | Delete | View
charToAction :: Char -> Maybe Action
charToAction x = case toUpper x of
'A' -> Just Add
'V' -> Just View
'D' -> Just Delete
_ -> Nothing
mainLoop :: TodoList -> IO ()
mainLoop xs = do
hSetBuffering stdin NoBuffering
putStrLn "Do you wish to [A]dd, [D]elete, [V]iew, or [E]xit? "
c <- getLine
when (toUpper (head c) /= 'E') $
case charToAction (head c) of
Nothing -> putStrLn "Unsupported operation"
Just act -> todoOp xs act >> mainLoop xs