52700.fb2 Учебник по Haskell - читать онлайн бесплатно полную версию книги . Страница 146

Учебник по Haskell - читать онлайн бесплатно полную версию книги . Страница 146

input file: fsldfksld

input file: sd;fls;dfl;vll; d;fld;f

input file: dflks;ldkf ldkfldkfld

input file: lsdkfksdlf ksdkflsdfkls;dfk

input file: bfk

input file: test

Hello!Hi)

input text: HowHow

Функция будет запрашивать файл до тех пор, пока мы не введём корректное значение. Мы можем доба-

вить сообщение об ошибке, немного изменив функцию обработки:

main = try ‘catch‘ const (msg >> main)

where msg = putStrLn ”Wrong filename, try again.”

А что делать если нам хочется различать ошибки по типу и предпринимать различные действия в зави-

симости от типа ошибки? Ошибки распознаются с помощью специальных предикатов, которые определены

в модуле System.IO.Error. Рассмотрим некоторые из них.

136 | Глава 8: IO

Например с помощью с помощью предиката isDoesNotExistErrorType мы можем опознать ошибки,

которые случились из-за того, что один из аргументов функции не существует. С помощью предиката

isPermissionErrorType мы можем узнать, что ошибка произошла из-за того, что мы пытались получить до-

ступ к данным, на которые у нас нет прав. Мы можем, немного изменив функцию-обработчик исключений,

выводить более информативные сообщения об ошибках перед перезапуском:

main = try ‘catch‘ handler

handler :: IOError -> IO ()

handler = ( >> main) . putStrLn . msg2 . msg1

msg1 e

| isDoesNotExistErrorType e = ”File does not exist. ”

| isPermissionErrorType e

= ”Access denied. ”

| otherwise

= ””

msg2 = (++ ”Try again.”)

В модуле System.IO.Error вы можете найти ещё много разных предикатов.

Потоки текстовых данных

Обмен данными, чтение и запись происходят с помощью потоков. Каждый поток имеет дескриптор

(handle), через него мы можем общаться с потоком, например считывать данные или записывать. Функции

для работы с потоками данных определены в модуле System.IO.

В любой момент в системе открыты три стандартных потока:

• stdin – стандартный ввод

• stdout – стандартный вывод

• stderr – поток ошибок и отладочных сообщений

Например когда мы выводим строку на экран, на самом деле мы записываем строку в поток stdout. А

когда мы читаем символ с клавиатуры, мы считываем его из потока stdin.

Файлы также являются потоками. При открытии файлу присваивается дескриптор через который, мы

можем обмениваться данными. Файл может быть открыт для чтения, записи, дополнения (записи в конец

файла) или чтения и записи. Файл открывается функцией:

openFile :: FilePath -> IOMode -> IO Handle

Функция принимает путь к файлу и режим работы с файлом и возвращает дескриптор. Режим может

принимать одно из значений:

ReadMode – чтение

WriteMode – запись