LINUX.ORG.RU

Haskell и обработка исключений.

 , ,


1

1

Вот у меня такой странный вопрос: почему IO функции выбрасывают ошибки ? Я имею в виду зачем делать error в IO вообще ?

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

В документации по хаскелю сказано, что выбрасывание ошибок нужно делать, когда дальнейшее выполнение программы не имеет смысла. Например ошибка паттерн матчинга - есть ошибка программы, ведь ADT в хаскеле - практически часть алгоритма, и поэтому единственным способом избавления от ошибки является правка кода. Все остальные ошибки, к которым относятся все ошибки ввода-вывода являются не ошибками, а исключениями, и должны обрабатыватся вещами типа EitherT.

Ну действительно: разве это ошибка, когда файл не удается прочесть ? Разве должна программа из-за этого падать ? Я понимаю, что есть средства обработки ошибок, но эти средства позволяют лишь отловить ошибку и сделать некие действия, но не более. Ведь если прерывать вычисление, то теряются все монадные профиты.

Представьте, вот есть список действий IO, ваша задача выполнить все действия и сложить в список результат только тех, которые выполнились без ошибок, а те, что с ошибкой, просто игнорировать. Если решать это с помощью EitherT, то решение элементарное

ignoreErrors :: [EitherT IO a] -> IO [a]
ignoreErrors x = do
  y <- sequence $ map runEitherT x
  return $ rights y
При этом монада нам гарантирует, что никакая ленивость не помешает нам отловить все ошибки ввода-вывода которые могут возникнуть, что все монадические действия вычислятся как минимум до конструктора Either, ведь могут существовать и другие исключения, не только те, что связаны с вводом-выводом, но и некоторые исключения в вычислениях. Все это будет отловлено в тот момент, когда мы просто паттернматчим результат runEitherT с Left или с Right.

Если задача стоит просто выполнить действия и гарантировать, отсутсвтвие исключений во всех вычислениях, то это просто sequence или sequence_, в зависимости от того, нужен нам результат вычислений, или нет.

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

Отсюда у меня вопрос: о чем думали создатели хаскеля, когда вообще включали error в стандартную библиотеку, использовали ее во всех функциях (деление на ноль) и давали пользователю ей пользоваться. Взгляните на все библиотеки, они все используют выбрасывание ошибок, вместо обработки исключений. Либо я чего-то не понимаю, и выбрасывать ошибку - очень удобно и правильно, либо это фейл проектировщиков ?

Дискач.

PS. haters gonna hate

Ответ на: комментарий от anonymous

То есть, к обработке ошибок это не имеет никакого отношения, а зачем написал ?

s9gf4ult ★★
() автор топика
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.