Как работает обработка исключений в Haskell? - PullRequest
10 голосов
/ 06 сентября 2010
foldl1 (+) []

Как отловить полученную ошибку?

Ответы [ 3 ]

14 голосов
/ 06 сентября 2010

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

Это логические ошибки, обычно указывающие на ошибки вспецификация программы.

Они могут быть перехвачены в коде ввода-вывода (обычно на внешнем уровне программы) через обработчик исключений .

Например, для перехватаваш пропавший регистр для пустого списка,

{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE BangPatterns        #-}

import Control.Exception

main = do
    handle (\(e :: SomeException) -> print $ "This program as a bug: " ++ show e) $ do
        let !v = foldl1 (+) ([] :: [Int])
        return ()

Мы можем наблюдать, что исключение перехватывается, и программа завершается.

$ ./A
"This program as a bug: Prelude.foldl1: empty list"
6 голосов
/ 06 сентября 2010
4 голосов
/ 06 сентября 2010

Пуристический ответ: результат не определен (в частности, bottom ). Вы не можете ничего с этим сделать, кроме сбоя, если значение каким-либо образом используется для построения результатов программы. См. Haskell 98 Report section 3.1 . Он указывает, что такие «ошибки вызывают немедленное завершение программы и не могут быть перехвачены пользователем».

Лучше всего проверять входные значения и обрабатывать их ДО того, как они смогут зайти так далеко. Не используйте fold1, если список может содержать 0 элементов.

Однако на практике вы можете использовать методы из других ответов, чтобы перехватить их в IO при использовании GHC. Исключения не могут быть перехвачены в чистом (не-IO) коде, потому что возникновение исключения - это изменение потока управления - побочный эффект, а не чистое вычисление.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...