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

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

(”Тони Хоар”, ”Внутри любой большой программы всегда есть\

\ маленькая, что рвётся на свободу”),

(”Пифагор”, ”Не гоняйся за счастьем, оно всегда находится в тебе самом”),

(”Лао Цзы”, ”Путешествие в тысячу ли начинается с одного шага”)]

Функция format приводит цитату к виду приятному для чтения. Попробуем программу в интерпретаторе:

Prelude> :! ghc --make Quote -o hi

[1 of 1] Compiling Main

( Quote. hs, Quote. o )

Linking hi ...

Prelude> :! ./hi

Путешествие в тысячу ли начинается с одного шага

Лао Цзы

Типичные задачи IO | 135

Prelude> :! ./hi

Не гоняйся за счастьем, оно всегда находится в тебе самом

Пифагор

Исключения

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

так. Это типы Maybe и Either. Если функции не удалось вычислить значение она возвращает специальное

значение Nothing или Left reason, по которому следующая функция может опознать ошибку и предпринять

какие-нибудь действия. Так обрабатываются ошибки в чистых функциях. В этом разделе мы узнаем о том,

как обрабатываются ошибки, которые происходят при взаимодействии с внешним миром, ошибки, которые

происходят внутри типа IO.

Ошибки функций с побочными эффектами обрабатываются с помощью специальной функции catch, она

определена в Prelude:

catch :: IO a -> (IOError -> IO a) -> IO a

Эта функция принимает значение, которое содержит побочные эффекты и функцию, которая обрабаты-

вает исключительные ситуации. К примеру если мы попытаемся прочитать данные из файла, к которому у

нас нет доступа, произойдёт ошибка. Мы можем не дать программе упасть и обработать ошибку с помощью

функции catch.

Например программа, в которой мы дописывали данные в файл, упадёт, если мы передадим не существу-

ющий файл. Но мы можем исправить это поведение с помощью функции catch. Мы можем перезапускать

программу, если произошла ошибка:

module FileSafe where

import Control.Applicative

import Control.Monad

main = try ‘catch‘ const main

try = msg1 >> getLine >>= read >>= append

where read

file = readFile file >>= putStrLn >> return file

append file = msg2 >> getLine >>= appendFile file

msg1

= putStr ”input file: ”

msg2

= putStr ”input text: ”

Часто функции двух аргументов называют так, чтобы при инфиксной форме записи получалась фраза

из английского языка. Так если мы запишем catch в инфиксной форме получится очень наглядное выраже-

ние. Функция обработки ошибок реагирует на любую ошибку перезапуском программы. Попробуем взломать

программу:

*FileSafe> main