$ ./arg-test first second w00t "multi word arg"
ΠΡΠ³ΡΠΌΠ΅Π½ΡΡ ΠΊΠΎΠΌΠ°Π½Π΄Π½ΠΎΠΉ ΡΡΡΠΎΠΊΠΈ:
first
second
w00t
multi word arg
ΠΠΌΡ ΠΏΡΠΎΠ³ΡΠ°ΠΌΠΌΡ:
arg-test
ΠΡΡ Π±ΠΎΠ»ΡΡΠ΅ ΡΠ°Π»ΠΎΡΡΠ΅ΠΉ ΡΠΎ ΡΠΏΠΈΡΠΊΠΎΠΌ Π΄Π΅Π»
Π ΠΏΡΠ΅Π΄ΡΠ΄ΡΡΠΈΡ ΠΏΡΠΈΠΌΠ΅ΡΠ°Ρ ΠΌΡ ΠΏΠΈΡΠ°Π»ΠΈ ΠΎΡΠ΄Π΅Π»ΡΠ½ΡΠ΅ ΠΏΡΠΎΠ³ΡΠ°ΠΌΠΌΡ Π΄Π»Ρ Π΄ΠΎΠ±Π°Π²Π»Π΅Π½ΠΈΡ ΠΈ ΡΠ΄Π°Π»Π΅Π½ΠΈΡ Π·Π°Π΄Π°Π½ΠΈΠΉ Π² ΡΠΏΠΈΡΠΊΠ΅ Π΄Π΅Π». Π’Π΅ΠΏΠ΅ΡΡ ΠΌΡ ΡΠΎΠ±ΠΈΡΠ°Π΅ΠΌΡΡ ΠΎΠ±ΡΠ΅Π΄ΠΈΠ½ΠΈΡΡ ΠΈΡ Π² Π½ΠΎΠ²ΠΎΠ΅ ΠΏΡΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠ΅, Π° ΡΡΠΎ Π΅ΠΌΡ Π΄Π΅Π»Π°ΡΡ, Π±ΡΠ΄Π΅ΠΌ ΡΠΊΠ°Π·ΡΠ²Π°ΡΡ Π² ΠΊΠΎΠΌΠ°Π½Π΄Π½ΠΎΠΉ ΡΡΡΠΎΠΊΠ΅. ΠΡΠΎΠΌΠ΅ ΡΠΎΠ³ΠΎ, ΠΏΠΎΠ·Π°Π±ΠΎΡΠΈΠΌΡΡ ΠΎ ΡΠΎΠΌ, ΡΡΠΎΠ±Ρ ΠΏΡΠΎΠ³ΡΠ°ΠΌΠΌΠ° ΡΠΌΠΎΠ³Π»Π° ΡΠ°Π±ΠΎΡΠ°ΡΡ Ρ ΡΠ°Π·Π½ΡΠΌΠΈ ΡΠ°ΠΉΠ»Π°ΠΌΠΈ β Π½Π΅ ΡΠΎΠ»ΡΠΊΠΎ todo.txt.
ΠΠ°Π·ΠΎΠ²ΡΠΌ ΠΏΡΠΎΠ³ΡΠ°ΠΌΠΌΡ ΠΏΡΠΎΡΡΠΎ todo, ΠΎΠ½Π° ΡΠΌΠΎΠΆΠ΅Ρ Π΄Π΅Π»Π°ΡΡ ΡΡΠΈ ΡΠ°Π·Π½ΡΠ΅ Π²Π΅ΡΠΈ:
β’ ΠΏΡΠΎΡΠΌΠ°ΡΡΠΈΠ²Π°ΡΡ Π·Π°Π΄Π°Π½ΠΈΡ;
β’ Π΄ΠΎΠ±Π°Π²Π»ΡΡΡ Π·Π°Π΄Π°Π½ΠΈΡ;
β’ ΡΠ΄Π°Π»ΡΡΡ Π·Π°Π΄Π°Π½ΠΈΡ.
ΠΠ»Ρ Π΄ΠΎΠ±Π°Π²Π»Π΅Π½ΠΈΡ Π½ΠΎΠ²ΠΎΠ³ΠΎ Π·Π°Π΄Π°Π½ΠΈΡ Π² ΡΠΏΠΈΡΠΎΠΊ Π΄Π΅Π» Π² ΡΠ°ΠΉΠ»Π΅ todo.txt ΠΌΡ Π±ΡΠ΄Π΅ΠΌ ΠΏΠΈΡΠ°ΡΡ:
$ ./todo add todo.txt "ΠΠ°ΠΉΡΠΈ ΠΌΠ°Π³ΠΈΡΠ΅ΡΠΊΠΈΠΉ ΠΌΠ΅Ρ ΡΠΈΠ»Ρ"
ΠΡΠΎΡΠΌΠΎΡΡΠ΅ΡΡ ΡΠ΅ΠΊΡΡΠΈΠ΅ Π·Π°Π΄Π°Π½ΠΈΡ ΠΌΠΎΠΆΠ½ΠΎ Π±ΡΠ΄Π΅Ρ ΠΊΠΎΠΌΠ°Π½Π΄ΠΎΠΉ view:
$ ./todo view todo.txt
ΠΠ»Ρ ΡΠ΄Π°Π»Π΅Π½ΠΈΡ Π·Π°Π΄Π°Π½ΠΈΡ ΠΏΠΎΡΡΠ΅Π±ΡΠ΅ΡΡΡ Π΄ΠΎΠΏΠΎΠ»Π½ΠΈΡΠ΅Π»ΡΠ½ΠΎ ΡΠΊΠ°Π·Π°ΡΡ Π΅Π³ΠΎ ΠΈΠ½Π΄Π΅ΠΊΡ:
$ ./todo remove todo.txt 2
ΠΠ½ΠΎΠ³ΠΎΠ·Π°Π΄Π°ΡΠ½ΡΠΉ ΡΠΏΠΈΡΠΎΠΊ Π·Π°Π΄Π°Ρ
ΠΠ°ΡΠ½ΡΠΌ Ρ ΡΠ΅Π°Π»ΠΈΠ·Π°ΡΠΈΠΈ ΡΡΠ½ΠΊΡΠΈΠΈ, ΠΊΠΎΡΠΎΡΠ°Ρ ΠΏΡΠΈΠ½ΠΈΠΌΠ°Π΅Ρ ΠΊΠΎΠΌΠ°Π½Π΄Ρ Π² Π²ΠΈΠ΄Π΅ ΡΡΡΠΎΠΊΠΈ (Π½Π°ΠΏΡΠΈΠΌΠ΅Ρ, "add" ΠΈΠ»ΠΈ "view") ΠΈ Π²ΠΎΠ·Π²ΡΠ°ΡΠ°Π΅Ρ ΡΡΠ½ΠΊΡΠΈΡ, ΠΊΠΎΡΠΎΡΠ°Ρ Π² ΡΠ²ΠΎΡ ΠΎΡΠ΅ΡΠ΅Π΄Ρ ΠΏΡΠΈΠ½ΠΈΠΌΠ°Π΅Ρ ΡΠΏΠΈΡΠΎΠΊ Π°ΡΠ³ΡΠΌΠ΅Π½ΡΠΎΠ² ΠΈ Π²ΠΎΠ·Π²ΡΠ°ΡΠ°Π΅Ρ Π΄Π΅ΠΉΡΡΠ²ΠΈΠ΅ Π²Π²ΠΎΠ΄Π°-Π²ΡΠ²ΠΎΠ΄Π°, Π²ΡΠΏΠΎΠ»Π½ΡΡΡΠ΅Π΅ Π² ΡΠΎΡΠ½ΠΎΡΡΠΈ ΡΠΎ, ΡΡΠΎ Π½Π΅ΠΎΠ±Ρ ΠΎΠ΄ΠΈΠΌΠΎ:
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 Π±ΡΠ΄Π΅Ρ Π²ΡΠ³Π»ΡΠ΄Π΅ΡΡ ΡΠ°ΠΊ:
main = do
(command:argList) <- getArgs
dispatch command argList
ΠΠ΅ΡΠ²ΡΠΌ Π΄Π΅Π»ΠΎΠΌ ΠΌΡ ΠΏΠΎΠ»ΡΡΠ°Π΅ΠΌ Π°ΡΠ³ΡΠΌΠ΅Π½ΡΡ ΠΈ ΡΠ²ΡΠ·ΡΠ²Π°Π΅ΠΌ ΠΈΡ ΡΠΎ ΡΠΏΠΈΡΠΊΠΎΠΌ (command:argsList). Π’Π°ΠΊΠΈΠΌ ΠΎΠ±ΡΠ°Π·ΠΎΠΌ, ΠΏΠ΅ΡΠ²ΡΠΉ Π°ΡΠ³ΡΠΌΠ΅Π½Ρ Π±ΡΠ΄Π΅Ρ ΡΠ²ΡΠ·Π°Π½ Ρ ΠΈΠΌΠ΅Π½Π΅ΠΌ command, Π° Π²ΡΠ΅ ΠΎΡΡΠ°Π»ΡΠ½ΡΠ΅ β ΡΠΎ ΡΠΏΠΈΡΠΊΠΎΠΌ argList. Π ΡΠ»Π΅Π΄ΡΡΡΠ΅ΠΉ ΡΡΡΠΎΠΊΠ΅ ΠΊ ΠΏΠ΅ΡΠ΅ΠΌΠ΅Π½Π½ΠΎΠΉ commands ΠΏΡΠΈΠΌΠ΅Π½ΡΠ΅ΡΡΡ ΡΡΠ½ΠΊΡΠΈΡ dispatch, ΡΠ΅Π·ΡΠ»ΡΡΠ°ΡΠΎΠΌ ΠΊΠΎΡΠΎΡΠΎΠΉ ΠΌΠΎΠΆΠ΅Ρ Π±ΡΡΡ ΠΎΠ΄Π½Π° ΠΈΠ· ΡΡΠ½ΠΊΡΠΈΠΉ add, view ΠΈΠ»ΠΈ remove. ΠΠ°ΡΠ΅ΠΌ ΡΠ΅Π·ΡΠ»ΡΡΠΈΡΡΡΡΠ°Ρ ΡΡΠ½ΠΊΡΠΈΡ ΠΏΡΠΈΠΌΠ΅Π½ΡΠ΅ΡΡΡ ΠΊ ΡΠΏΠΈΡΠΊΡ Π°ΡΠ³ΡΠΌΠ΅Π½ΡΠΎΠ² argList.
ΠΡΠ΅Π΄ΠΏΠΎΠ»ΠΎΠΆΠΈΠΌ, ΠΏΡΠΎΠ³ΡΠ°ΠΌΠΌΠ° Π·Π°ΠΏΡΡΠ΅Π½Π° ΡΠΎ ΡΠ»Π΅Π΄ΡΡΡΠΈΠΌΠΈ ΠΏΠ°ΡΠ°ΠΌΠ΅ΡΡΠ°ΠΌΠΈ:
$ ./todo add todo.txt "ΠΠ°ΠΉΡΠΈ ΠΌΠ°Π³ΠΈΡΠ΅ΡΠΊΠΈΠΉ ΠΌΠ΅Ρ ΡΠΈΠ»Ρ"
Π’ΠΎΠ³Π΄Π° Π·Π½Π°ΡΠ΅Π½ΠΈΠ΅ΠΌ command Π±ΡΠ΄Π΅Ρ "add", Π° Π·Π½Π°ΡΠ΅Π½ΠΈΠ΅ΠΌ argList β ΡΠΏΠΈΡΠΎΠΊ ["todo.txt", "ΠΠ°ΠΉΡΠΈ ΠΌΠ°Π³ΠΈΡΠ΅ΡΠΊΠΈΠΉ ΠΌΠ΅Ρ ΡΠΈΠ»Ρ"]. ΠΠΎΡΡΠΎΠΌΡ ΡΡΠ°Π±ΠΎΡΠ°Π΅Ρ ΠΏΠ΅ΡΠ²ΡΠΉ Π²Π°ΡΠΈΠ°Π½Ρ ΠΎΠΏΡΠ΅Π΄Π΅Π»Π΅Π½ΠΈΡ ΡΡΠ½ΠΊΡΠΈΠΈ dispatch ΠΈ Π±ΡΠ΄Π΅Ρ Π²ΠΎΠ·Π²ΡΠ°ΡΠ΅Π½Π° ΡΡΠ½ΠΊΡΠΈΡ add. ΠΡΠΈΠΌΠ΅Π½ΡΠ΅ΠΌ Π΅Ρ ΠΊ argList, ΡΠ΅Π·ΡΠ»ΡΡΠ°ΡΠΎΠΌ ΠΎΠΊΠ°Π·ΡΠ²Π°Π΅ΡΡΡ Π΄Π΅ΠΉΡΡΠ²ΠΈΠ΅ Π²Π²ΠΎΠ΄Π°-Π²ΡΠ²ΠΎΠ΄Π°, Π΄ΠΎΠ±Π°Π²Π»ΡΡΡΠ΅Π΅ Π½ΠΎΠ²ΠΎΠ΅ Π·Π°Π΄Π°Π½ΠΈΠ΅ Π² ΡΠΏΠΈΡΠΎΠΊ.
Π’Π΅ΠΏΠ΅ΡΡ Π΄Π°Π²Π°ΠΉΡΠ΅ ΡΠ΅Π°Π»ΠΈΠ·ΡΠ΅ΠΌ ΡΡΠ½ΠΊΡΠΈΠΈ add, view ΠΈ remove. ΠΠ°ΡΠ½ΡΠΌ Ρ ΠΏΠ΅ΡΠ²ΠΎΠΉ ΠΈΠ· Π½ΠΈΡ :
add :: [String] β> IO ()
add [fileName, todoItem] = appendFile fileName (todoItem ++ "\n")
ΠΡΠΈ Π²ΡΠ·ΠΎΠ²Π΅
$ ./todo add todo.txt "ΠΠ°ΠΉΡΠΈ ΠΌΠ°Π³ΠΈΡΠ΅ΡΠΊΠΈΠΉ ΠΌΠ΅Ρ ΡΠΈΠ»Ρ"
ΡΡΠ½ΠΊΡΠΈΠΈ add Π±ΡΠ΄Π΅Ρ ΠΏΠ΅ΡΠ΅Π΄Π°Π½ ΡΠΏΠΈΡΠΎΠΊ ["todo.txt", "ΠΠ°ΠΉΡΠΈ ΠΌΠ°Π³ΠΈΡΠ΅ΡΠΊΠΈΠΉ ΠΌΠ΅Ρ ΡΠΈΠ»Ρ"]. ΠΠΎΡΠΊΠΎΠ»ΡΠΊΡ ΠΏΠΎΠΊΠ° ΠΌΡ Π½Π΅ ΠΎΠ±ΡΠ°Π±Π°ΡΡΠ²Π°Π΅ΠΌ Π½Π΅ΠΊΠΎΡΡΠ΅ΠΊΡΠ½ΡΠΉ Π²Π²ΠΎΠ΄, Π΄ΠΎΡΡΠ°ΡΠΎΡΠ½ΠΎ Π±ΡΠ΄Π΅Ρ ΡΠΎΠΏΠΎΡΡΠ°Π²ΠΈΡΡ Π°ΡΠ³ΡΠΌΠ΅Π½Ρ ΡΡΠ½ΠΊΡΠΈΠΈ add Ρ Π΄Π²ΡΡ ΡΠ»Π΅ΠΌΠ΅Π½ΡΠ½ΡΠΌ ΡΠΏΠΈΡΠΊΠΎΠΌ. Π Π΅Π·ΡΠ»ΡΡΠ°ΡΠΎΠΌ ΡΡΠ½ΠΊΡΠΈΠΈ Π±ΡΠ΄Π΅Ρ Π΄Π΅ΠΉΡΡΠ²ΠΈΠ΅ Π²Π²ΠΎΠ΄Π°-Π²ΡΠ²ΠΎΠ΄Π°, Π΄ΠΎΠ±Π°Π²Π»ΡΡΡΠ΅Π΅ ΡΡΡΠΎΠΊΡ Π²ΠΌΠ΅ΡΡΠ΅ Ρ ΡΠΈΠΌΠ²ΠΎΠ»ΠΎΠΌ ΠΊΠΎΠ½ΡΠ° ΡΡΡΠΎΠΊΠΈ Π² ΠΊΠΎΠ½Π΅Ρ ΡΠ°ΠΉΠ»Π°.
ΠΠ°Π»Π΅Π΅ ΡΠ΅Π°Π»ΠΈΠ·ΡΠ΅ΠΌ ΡΡΠ½ΠΊΡΠΈΠΎΠ½Π°Π»ΡΠ½ΠΎΡΡΡ ΠΏΡΠΎΡΠΌΠΎΡΡΠ° ΡΠΏΠΈΡΠΊΠ°. ΠΡΠ»ΠΈ ΠΌΡ Ρ ΠΎΡΠΈΠΌ ΠΏΡΠΎΡΠΌΠΎΡΡΠ΅ΡΡ ΡΠ»Π΅ΠΌΠ΅Π½ΡΡ ΡΠΏΠΈΡΠΊΠ°, ΡΠΎ Π²ΡΠ·ΡΠ²Π°Π΅ΠΌ ΠΏΡΠΎΠ³ΡΠ°ΠΌΠΌΡ ΡΠ°ΠΊ: todo view todo.txt. Π ΠΏΠ΅ΡΠ²ΠΎΠΌ ΡΠΎΠΏΠΎΡΡΠ°Π²Π»Π΅Π½ΠΈΠΈ Ρ ΠΎΠ±ΡΠ°Π·ΡΠΎΠΌ ΠΈΠ΄Π΅Π½ΡΠΈΡΠΈΠΊΠ°ΡΠΎΡ command Π±ΡΠ΄Π΅Ρ ΡΠ²ΡΠ·Π°Π½ ΡΠΎ ΡΡΡΠΎΠΊΠΎΠΉ view, Π° ΠΈΠ΄Π΅Π½ΡΠΈΡΠΈΠΊΠ°ΡΠΎΡ argList Π±ΡΠ΄Π΅Ρ ΡΠ°Π²Π΅Π½ ["todo.txt"].
ΠΠΎΡ ΠΊΠΎΠ΄ ΡΡΠ½ΠΊΡΠΈΠΈ view:
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. Π€ΡΠ½ΠΊΡΠΈΡ Π±ΡΠ΄Π΅Ρ ΠΎΡΠ΅Π½Ρ ΠΏΠΎΡ ΠΎΠΆΠ° Π½Π° ΠΏΡΠΎΠ³ΡΠ°ΠΌΠΌΡ Π΄Π»Ρ ΡΠ΄Π°Π»Π΅Π½ΠΈΡ ΡΠ»Π΅ΠΌΠ΅Π½ΡΠ°, ΡΠ°ΠΊ ΡΡΠΎ Π΅ΡΠ»ΠΈ Π²Ρ Π½Π΅ ΠΏΠΎΠ½ΠΈΠΌΠ°Π΅ΡΠ΅, ΠΊΠ°ΠΊ ΡΠ°Π±ΠΎΡΠ°Π΅Ρ ΡΡΠ½ΠΊΡΠΈΡ ΡΠ΄Π°Π»Π΅Π½ΠΈΡ, ΠΏΡΠΎΡΠΈΡΠ°ΠΉΡΠ΅ ΠΏΠΎΡΡΠ½Π΅Π½ΠΈΡ ΠΊ Π΅Ρ ΠΎΠΏΡΠ΅Π΄Π΅Π»Π΅Π½ΠΈΡ. ΠΡΠ½ΠΎΠ²Π½ΠΎΠ΅ ΠΎΡΠ»ΠΈΡΠΈΠ΅ β ΠΌΡ Π½Π΅ Π·Π°Π΄Π°ΡΠΌ ΠΆΡΡΡΠΊΠΎ ΠΈΠΌΡ ΡΠ°ΠΉΠ»Π°, Π° ΠΏΠΎΠ»ΡΡΠ°Π΅ΠΌ Π΅Π³ΠΎ ΠΊΠ°ΠΊ Π°ΡΠ³ΡΠΌΠ΅Π½Ρ. Π’Π°ΠΊΠΆΠ΅ ΠΌΡ Π½Π΅ ΡΠΏΡΠ°ΡΠΈΠ²Π°Π΅ΠΌ Ρ ΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°ΡΠ΅Π»Ρ Π½ΠΎΠΌΠ΅Ρ Π·Π°Π΄Π°ΡΠΈ Π΄Π»Ρ ΡΠ΄Π°Π»Π΅Π½ΠΈΡ β Π΅Π³ΠΎ ΠΌΡ ΡΠ°ΠΊΠΆΠ΅ ΠΏΠΎΠ»ΡΡΠ°Π΅ΠΌ Π² Π²ΠΈΠ΄Π΅ Π°ΡΠ³ΡΠΌΠ΅Π½ΡΠ°.
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)
ΠΡ ΠΎΡΠΊΡΡΠ²Π°Π΅ΠΌ ΡΠ°ΠΉΠ», ΠΏΠΎΠ»Π½ΠΎΠ΅ ΠΈΠΌΡ ΠΊΠΎΡΠΎΡΠΎΠ³ΠΎ Π·Π°Π΄Π°ΡΡΡΡ Π² ΠΈΠ΄Π΅Π½ΡΠΈΡΠΈΠΊΠ°ΡΠΎΡΠ΅ fileName, ΠΎΡΠΊΡΡΠ²Π°Π΅ΠΌ Π²ΡΠ΅ΠΌΠ΅Π½Π½ΡΠΉ ΡΠ°ΠΉΠ», ΡΠ΄Π°Π»ΡΠ΅ΠΌ ΡΡΡΠΎΠΊΡ ΠΏΠΎ ΠΈΠ½Π΄Π΅ΠΊΡΡ, Π·Π°ΠΏΠΈΡΡΠ²Π°Π΅ΠΌ Π²ΠΎ Π²ΡΠ΅ΠΌΠ΅Π½Π½ΡΠΉ ΡΠ°ΠΉΠ», ΡΠ΄Π°Π»ΡΠ΅ΠΌ ΠΈΡΡ ΠΎΠ΄Π½ΡΠΉ ΡΠ°ΠΉΠ» ΠΈ ΠΏΠ΅ΡΠ΅ΠΈΠΌΠ΅Π½ΠΎΠ²ΡΠ²Π°Π΅ΠΌ Π²ΡΠ΅ΠΌΠ΅Π½Π½ΡΠΉ Π² fileName. ΠΡΠΈΠ²Π΅Π΄ΡΠΌ ΠΏΠΎΠ»Π½ΡΠΉ Π»ΠΈΡΡΠΈΠ½Π³ ΠΏΡΠΎΠ³ΡΠ°ΠΌΠΌΡ Π²ΠΎ Π²ΡΠ΅ΠΉ Π΅Ρ ΠΊΡΠ°ΡΠ΅:
import System.Environment
import System.Directory
import System.IO
import Control.Exception
import Data.List
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)
Π Π΅Π·ΡΠΌΠΈΡΡΠ΅ΠΌ Π½Π°ΡΠ΅ ΡΠ΅ΡΠ΅Π½ΠΈΠ΅. ΠΡ Π½Π°ΠΏΠΈΡΠ°Π»ΠΈ ΡΡΠ½ΠΊΡΠΈΡ dispatch, ΠΎΡΠΎΠ±ΡΠ°ΠΆΠ°ΡΡΡΡ ΠΊΠΎΠΌΠ°Π½Π΄Ρ Π½Π° ΡΡΠ½ΠΊΡΠΈΠΈ, ΠΊΠΎΡΠΎΡΡΠ΅ ΠΏΡΠΈΠ½ΠΈΠΌΠ°ΡΡ Π°ΡΠ³ΡΠΌΠ΅Π½ΡΡ ΠΊΠΎΠΌΠ°Π½Π΄Π½ΠΎΠΉ ΡΡΡΠΎΠΊΠΈ Π² Π²ΠΈΠ΄Π΅ ΡΠΏΠΈΡΠΊΠ° ΠΈ Π²ΠΎΠ·Π²ΡΠ°ΡΠ°ΡΡ ΡΠΎΠΎΡΠ²Π΅ΡΡΡΠ²ΡΡΡΠ΅Π΅ Π΄Π΅ΠΉΡΡΠ²ΠΈΠ΅ Π²Π²ΠΎΠ΄Π°-Π²ΡΠ²ΠΎΠ΄Π°. ΠΡΠ½ΠΎΠ²ΡΠ²Π°ΡΡΡ Π½Π° Π·Π½Π°ΡΠ΅Π½ΠΈΠΈ ΠΏΠ΅ΡΠ²ΠΎΠ³ΠΎ Π°ΡΠ³ΡΠΌΠ΅Π½ΡΠ°, ΡΡΠ½ΠΊΡΠΈΡ dispatch Π΄Π°ΡΡ Π½Π°ΠΌ Π½Π΅ΠΎΠ±Ρ ΠΎΠ΄ΠΈΠΌΡΡ ΡΡΠ½ΠΊΡΠΈΡ. Π ΡΠ΅Π·ΡΠ»ΡΡΠ°ΡΠ΅ Π²ΡΠ·ΠΎΠ²Π° ΡΡΠΎΠΉ ΡΡΠ½ΠΊΡΠΈΠΈ ΠΌΡ ΠΏΠΎΠ»ΡΡΠ°Π΅ΠΌ ΡΡΠ΅Π±ΡΠ΅ΠΌΠΎΠ΅ Π΄Π΅ΠΉΡΡΠ²ΠΈΠ΅ ΠΈ Π²ΡΠΏΠΎΠ»Π½ΡΠ΅ΠΌ Π΅Π³ΠΎ.
ΠΠ°Π²Π°ΠΉΡΠ΅ ΠΏΡΠΎΠ²Π΅ΡΠΈΠΌ, ΠΊΠ°ΠΊ Π½Π°ΡΠ° ΠΏΡΠΎΠ³ΡΠ°ΠΌΠΌΠ° ΡΠ°Π±ΠΎΡΠ°Π΅Ρ:
$ ./todo view todo.txt
0 β ΠΠΎΠ³Π»Π°Π΄ΠΈΡΡ ΠΏΠΎΡΡΠ΄Ρ
1 β ΠΠΎΠΌΡΡΡ ΡΠΎΠ±Π°ΠΊΡ
2 β ΠΡΠ½ΡΡΡ ΡΠ°Π»Π°Ρ ΠΈΠ· ΠΏΠ΅ΡΠΈ
$ ./todo add todo.txt "ΠΠ°Π±ΡΠ°ΡΡ Π΄Π΅ΡΠ΅ΠΉ ΠΈΠ· Ρ ΠΈΠΌΡΠΈΡΡΠΊΠΈ"
$ ./todo view todo.txt
0 β ΠΠΎΠ³Π»Π°Π΄ΠΈΡΡ ΠΏΠΎΡΡΠ΄Ρ
1 β ΠΠΎΠΌΡΡΡ ΡΠΎΠ±Π°ΠΊΡ
2 β ΠΡΠ½ΡΡΡ ΡΠ°Π»Π°Ρ ΠΈΠ· ΠΏΠ΅ΡΠΈ
3 β ΠΠ°Π±ΡΠ°ΡΡ Π΄Π΅ΡΠ΅ΠΉ ΠΈΠ· Ρ ΠΈΠΌΡΠΈΡΡΠΊΠΈ
$ ./todo remove todo.txt 2
$ ./todo view todo.txt
0 β ΠΠΎΠ³Π»Π°Π΄ΠΈΡΡ ΠΏΠΎΡΡΠ΄Ρ
1 β ΠΠΎΠΌΡΡΡ ΡΠΎΠ±Π°ΠΊΡ
2 β ΠΠ°Π±ΡΠ°ΡΡ Π΄Π΅ΡΠ΅ΠΉ ΠΈΠ· Ρ ΠΈΠΌΡΠΈΡΡΠΊΠΈ
ΠΠΎΠ»ΡΡΠΎΠΉ ΠΏΠ»ΡΡ ΡΠ°ΠΊΠΎΠ³ΠΎ ΠΏΠΎΠ΄Ρ ΠΎΠ΄Π° β Π»Π΅Π³ΠΊΠΎ Π΄ΠΎΠ±Π°Π²Π»ΡΡΡ Π½ΠΎΠ²ΡΡ ΡΡΠ½ΠΊΡΠΈΠΎΠ½Π°Π»ΡΠ½ΠΎΡΡΡ. ΠΠΎΠ±Π°Π²ΠΈΡΡ Π²Π°ΡΠΈΠ°Π½Ρ ΠΎΠΏΡΠ΅Π΄Π΅Π»Π΅Π½ΠΈΡ ΡΡΠ½ΠΊΡΠΈΠΈ dispatch, ΡΠ΅Π°Π»ΠΈΠ·ΠΎΠ²Π°ΡΡ ΡΠΎΠΎΡΠ²Π΅ΡΡΡΠ²ΡΡΡΡΡ ΡΡΠ½ΠΊΡΠΈΡ β ΠΈ Π³ΠΎΡΠΎΠ²ΠΎ! Π ΠΊΠ°ΡΠ΅ΡΡΠ²Π΅ ΡΠΏΡΠ°ΠΆΠ½Π΅Π½ΠΈΡ ΠΌΠΎΠΆΠ΅ΡΠ΅ ΡΠ΅Π°Π»ΠΈΠ·ΠΎΠ²Π°ΡΡ ΡΡΠ½ΠΊΡΠΈΡ bump, ΠΊΠΎΡΠΎΡΠ°Ρ ΠΏΡΠΈΠΌΠ΅Ρ ΡΠ°ΠΉΠ» ΠΈ Π½ΠΎΠΌΠ΅Ρ Π·Π°Π΄Π°ΡΠΈ ΠΈ Π²Π΅ΡΠ½ΡΡ Π΄Π΅ΠΉΡΡΠ²ΠΈΠ΅ Π²Π²ΠΎΠ΄Π°-Π²ΡΠ²ΠΎΠ΄Π°, ΠΊΠΎΡΠΎΡΠΎΠ΅ ΠΏΠΎΠ΄Π½ΠΈΠΌΠ΅Ρ ΡΠΊΠ°Π·Π°Π½Π½ΡΡ Π·Π°Π΄Π°ΡΡ Π½Π° Π²Π΅ΡΡΠΈΠ½Ρ ΡΠΏΠΈΡΠΊΠ° Π·Π°Π΄Π°Ρ.
Π Π°Π±ΠΎΡΠ°Π΅ΠΌ Ρ Π½Π΅ΠΊΠΎΡΡΠ΅ΠΊΡΠ½ΡΠΌ Π²Π²ΠΎΠ΄ΠΎΠΌ
ΠΠΎΠΆΠ½ΠΎ Π±ΡΠ»ΠΎ Π±Ρ Π΄ΠΎΠΏΠΈΡΠ°ΡΡ ΡΡΡ ΠΏΡΠΎΠ³ΡΠ°ΠΌΠΌΡ, ΡΠ»ΡΡΡΠΈΠ² ΡΠΎΠΎΠ±ΡΠ΅Π½ΠΈΡ ΠΎΠ± ΠΎΡΠΈΠ±ΠΊΠ°Ρ , Π²ΠΎΠ·Π½ΠΈΠΊΠ°ΡΡΠΈΡ ΠΏΡΠΈ Π½Π΅ΠΊΠΎΡΡΠ΅ΠΊΡΠ½ΡΡ ΠΈΡΡ ΠΎΠ΄Π½ΡΡ Π΄Π°Π½Π½ΡΡ . ΠΠ°ΡΠ°ΡΡ ΠΌΠΎΠΆΠ½ΠΎ Ρ Π΄ΠΎΠ±Π°Π²Π»Π΅Π½ΠΈΡ Π²Π°ΡΠΈΠ°Π½ΡΠ° ΡΡΠ½ΠΊΡΠΈΠΈ dispatch, ΠΊΠΎΡΠΎΡΡΠΉ ΡΡΠ°Π±Π°ΡΡΠ²Π°Π΅Ρ ΠΏΡΠΈ Π»ΡΠ±ΠΎΠΉ Π½Π΅ΡΡΡΠ΅ΡΡΠ²ΡΡΡΠ΅ΠΉ ΠΊΠΎΠΌΠ°Π½Π΄Π΅:
dispatch :: String -> [String] -> IO ()
dispatch "add" = add
dispatch "view" = view
dispatch "remove" = remove
dispatch command = doesntExist command
doesntExist :: String -> [String] -> IO ()
doesntExist command _ =
putStrLn $ "ΠΠΎΠΌΠ°Π½Π΄Π° " ++ command ++ " Π½Π΅ ΠΎΠΏΡΠ΅Π΄Π΅Π»Π΅Π½Π°"
Π’Π°ΠΊΠΆΠ΅ ΠΌΠΎΠΆΠ½ΠΎ Π΄ΠΎΠ±Π°Π²ΠΈΡΡ Π²Π°ΡΠΈΠ°Π½ΡΡ ΠΎΠΏΡΠ΅Π΄Π΅Π»Π΅Π½ΠΈΡ ΡΡΠ½ΠΊΡΠΈΠΉ add, view ΠΈ remove Π΄Π»Ρ ΡΠ»ΡΡΠ°Π΅Π², ΠΊΠΎΠ³Π΄Π° ΠΏΡΠΎΠ³ΡΠ°ΠΌΠΌΠ΅ ΠΏΠ΅ΡΠ΅Π΄Π°Π½ΠΎ Π½Π΅ΠΏΡΠ°Π²ΠΈΠ»ΡΠ½ΠΎΠ΅ ΠΊΠΎΠ»ΠΈΡΠ΅ΡΡΠ²ΠΎ Π°ΡΠ³ΡΠΌΠ΅Π½ΡΠΎΠ². ΠΠ°ΠΏΡΠΈΠΌΠ΅Ρ: