Изучай Haskell во имя добра! (Липовача) - страница 136

мы печатаем каждое задание на отдельной строке, после чего спрашиваем пользователя, что он хочет удалить, и ждём его ответа. Например, он хочет удалить задание 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