Обратите внимание, что программист, использующий такого рода функции, не работает непосредственно с исключениями – ему лишь достаточно понимать логику и порядок вызова конкретных действий.
Модуль >Control.Exception
содержит ещё несколько подобных функций. Функция >finally
обеспечивает гарантированное выполнение некоторого действия по завершении другого действия. Это всего навсего упрощённый вариант функции >bracket
. Вот её сигнатура:
>finally :: IO a -> IO b -> IO a
В следующем примере текст >"Готово!"
печатается в каждом из двух случаев, несмотря на возникновение исключения во втором:
>ghci> print (20 `div` 10) `finally` putStrLn "Готово!"
>2
>Готово!
>ghci> print (2 `div` 0) `finally` putStrLn "Готово!"
>Готово!
>*** Exception: divide by zero
Функция >onException
позволяет выполнить заключительное действие только в случае возникновения исключения:
>ghci> print (20 `div` 10) `onException` putStrLn "Ошибка!"
>2
>ghci> print (2 `div` 0) `finally` putStrLn "Ошибка!"
>Ошибка!
>*** Exception: divide by zero
Заметьте, что обе эти функции, в отличие от >try
или >catch
, не обрабатывают исключения – они лишь гарантируют выполнение указанных действий. Все эти функции нетрудно реализовать вручную, пользуясь лишь >try
или >catch
. Фактически они устанавливают свой обработчик, перехватывают исключение, выполняют заданные действия, а после этого повторно генерируют то же самое исключение. Тем не менее, если ваша задача соответствует одному из приведённых сценариев, стоит воспользоваться уже существующей функцией.