[haskell] обработка ошибок с помощью исключений
Если видишь ступенеобразную конструкцию, значит надо использовать монаду. В данном случае есть даже некий выбор монад. Maybe, Either, Control.Exception, Control.Monad.Error.
Использование монады в данном случае не дает никакого улучшения и не решает проблему написания однообразного кода в больших количествах. Если ты не согласен --- приведи пример кода.
data ErrVal a = OK a | Error Exception
return x = OK x
fail x = Error x
m =>> f =
case m of
OK x -> f x
Error x -> Error x
do
v1 <- f a
v2 <- g b
v3 <- h c
return $ v1 + v2 + v3
Рассмотрим такую ситуацию: f1 вызывает f2, f2 вызывает f3, ..., f19 вызывает в f20.
Предположим, в f20 кидается исключение, в f1 оно ловится.
В подходе, используемом в Java, C# --- f2, f3, ..., f19 не знают про исключение.
В Haskell функции f2, ..., f19 должны знать про исключение, что сильно увеличивает размер программ (не содержательно, а требуя везде расстановки всяких do, IO не относящихся к смыслу программы.
Что самое важное, сильно увеличивается связность. Если например, f20 раньше не кидало исключения, а теперь стало кидать, или же стало кидать новые типы исключений, то придется перепеписывать f2-f19. Все функции становятся зависимыми, что ставит крест на модульном программировании.
IMHO возможность разделения программы на куски, которые можно писать независимо, более важна чем любые языкове фичи типа монад, type inference итп.
У меня есть 2 гипотезы
1) это такой геморой, который невозможно обойти.
2) мы просто не знаем, что такие вещи можно делать как-то иначе. Надо посмотреть исходники GHC.
Ааа! То есть, в ленивом языке g может быть вызван раньше, чем f и соответственно непонятно, какой exception кидать? Вот в чем фишка!
Не работал с ленивыми языками, поэтому сразу не дошло.
Получается проблема глубже, чем я изначально предполагал.
http://research.microsoft.com/~simonpj/Papers/imprecise-exn....
IMHO толково написано, проливает свет на подобные вопросы.
Вот что удалось найти в Google: IMHO толково написано, проливает свет на подобные вопросы.
Оставить комментарий
Landstreicher
Предположим я вычисляю некоторое выражение, в процессе его вычисления могут возникать некоторые ошибки (деление на 0, неправильная функция, нет места на диске итп).Почти во всех современных языках (в том числе C++,C#,Java,ML,Lisp,Python) я могу написать примерно следующее:
В Lisp даже есть возможность спросить что-то у пользователя, поменять что-то, а затем назад вернуться в то место, где была ошибка и продолжить работу (handler-bind, restart итп).
Насколько я понимаю, эквивалентная функциональность в Haskell-е реализуется следующим образом:
Такой способ, возвращает нас в старые добрые 70-ые годы, когда никаких еще исключений в помине не было, функции возвращали код возврата, который надо было проверять руками по типа if (result == -1) { ... }.
Вопрос: есть ли какой-нибудь способ реализовать нормальную обработку исключений в Haskell-е, так чтобы не пришлось писать кучу однообразного кода?