Что делать, если в процессе операций ввода/вывода возникла неординарная ситуация? Например, функция getChar обнаружила конец файла. В этом случае произойдет ошибка. Как и любой продвинутый язык программирования Haskell предлагает для этих целей механизм обработки исключений. Для этого не используется какой-то специальный синтаксис, но есть специальный тип IOError, который содержит описания всех возникаемых в процессе ввода/вывода ошибок.
Обработчик исключений имеет тип (IOError ® IO a), при этом функция catch ассоциирует (связывает) обработчик исключений с набором действий:
catch :: IO a -> (IOError -> IO a) -> IO a
Аргументами этой функции являются действие (первый аргумент) и обработчик исключений (второй аргумент). Если действие выполнено успешно, то просто возвращается результат без возбуждения обработчика исключений. Если же в процессе выполнения действия возникла ошибка, то она передается обработчику исключений в качестве операнда типа IOError, после чего выполняется сам обработчик.
Таким образом, можно написать более сложные функции, которые будут грамотно вести себя в случае выпадения ошибочных ситуаций:
getChar’ :: IO Char
getChar’ = getChar `catch` eofHandler
where eofHandler e = if isEOFError e then return ’\n’ else ioError e
getLine’ :: IO String
getLine’ = catch getLine’’ (\err -> return (”Error: ” ++ show err))
where getLine’’ = do c <- getChar’
if c == ’\n’ then return ””
else do l <- getLine’
return (c : l)
В этой программе видно, что можно использовать вложенные друг в друга обработчики ошибок. В функции getChar’ отлавливается ошибка, которая возникает при обнаружении символа конца файла. Если ошибка другая, то при помощи функции ioError она отправляется дальше и ловится обработчиком, который "сидит" в функции getLine’. Для определённости в Haskell’е предусмотрен обработчик исключений по умолчанию, который находится на самом верхнем уровне вложенности. Если ошибка не поймана ни одним обработчиком, который написан в программе, то её ловит обработчик по умолчанию, который выводит на экран сообщение об ошибке и останавливает программу.