мы печатаем каждое задание на отдельной строке, после чего спрашиваем пользователя, что он хочет удалить, и ждём его ответа. Например, он хочет удалить задание 1 (Помыть собаку), так что мы получим число >1
. Значением переменной >numberString
будет >"1"
, и, поскольку вместо строки нам необходимо число, мы применяем функцию >read
и связываем результат с именем >number
.
Помните функции >delete
и >!!
из модуля >Data.List
? Оператор >!!
возвращает элемент из списка по индексу, функция >delete
удаляет первое вхождение элемента в список, возвращая новый список без удалённого элемента. Выражение (>todoTasks !! number
), где >number
– это >1
, возвращает строку >"Помыть
>собаку"
. Мы удаляем первое вхождение этой строки из списка >todoTasks
, собираем всё оставшееся в одну строку функцией >unlines
и даём результату имя >newTodoItems
.
Далее используем новую функцию из модуля >System.IO
– >openTempFile
. Имя функции говорит само за себя: >open temp file
– «открыть временный файл». Она принимает путь к временному каталогу и шаблон имени файла и открывает временный файл. Мы использовали символ >.
в качестве каталога для временных файлов, так как >.
обозначает текущий каталог практически во всех операционных системах. Строку >"temp"
мы указали в качестве шаблона имени для временного файла; это означает, что временный файл будет назван >temp
плюс несколько случайных символов. Функция возвращает действие ввода-вывода, которое создаст временный файл; результат действия – пара значений, имя временного файла и дескриптор. Мы могли бы открыть обычный файл, например с именем todo2.txt, но использовать >openTempFile
– хорошая практика: в этом случае не приходится опасаться, что вы случайно что-нибудь перезапишете.
Теперь, когда временный файл открыт, запишем туда строку >newTodoItems
. В этот момент исходный файл не изменён, а временный содержит все строки из исходного, за исключением удалённой.
Затем мы закрываем временный файл и удаляем исходный с помощью функции >removeFile
, которая принимает путь к файлу и удаляет его. После удаления старого файла todo.txt мы используем функцию >renameFile
, чтобы переименовать временный файл в todo.txt. Обратите внимание: функции >removeFile
и >renameFile
(обе они определены в модуле >System.Directory
) принимают в качестве параметров не дескрипторы, а пути к файлам.
Сохраните программу в файле с именем deletetodo.hs, скомпилируйте её и проверьте:
>$ ./deletetodo
>Ваши задания:
>0 – Погладить посуду
>1 – Помыть собаку
>2 – Вынуть салат из печи
>Что вы хотите удалить?
>1
Смотрим, что осталось:
>$ cat todo.txt