В чем идея библиотек на Haskell, вызывающих исключения - PullRequest
0 голосов
/ 25 октября 2018

Почему библиотека (wreq на 404, например) выдает исключение вместо того, чтобы обернуть результат во что-то вроде Maybe?

Наивно, я думаюMaybe было бы лучше (компилятор предупреждает меня, если я не обрабатываю все случаи, например).Почему я здесь не прав?

1 Ответ

0 голосов
/ 25 октября 2018

Haskellers действительно стремятся избегать выброса исключений из функций - функция должна генерировать исключение только в действительно исключительных случаях, то есть в ситуациях «этого никогда не должно происходить», например, когда пользователь передает какой-то ввод, который явно запрещенпо документации.Если бы чистые функции регулярно вызывали исключения, это было бы большой проблемой не только потому, что тип не говорит, что нужно подготовить для перехвата, а также один не может перехватывать исключения в чистой функции, но только вIO код, который вызывает функцию.И даже если вы в принципе можете поймать исключение, может быть трудно предсказать , где это нужно сделать, потому что ленивая оценка может отсрочить момент, когда это действительно происходит.

В сущностина самом деле, даже в случае, например, Wreq.get, исключение не выдается из функции .

Prelude Network.Wreq> get "htt:/p/this-isn't even valid URL syntax" `seq` "Ok"
"Ok"

Это IOдействие , которое выдает при его выполнении:

Prelude Network.Wreq> get "htt:/p/this-isn't even valid URL syntax" >> pure ()
*** Exception: InvalidUrlException "htt:/p/this-isn't%20even%20valid%20URL%20syntax" "Invalid scheme"

Теперь с действием IO ситуация несколько иная. Lots из IO действий могут иметь потенциально очень разные ошибки в разных ситуациях, которые могут быть трудно или невозможно предсказать, например, сбой жесткого диска.Каталогизация всех возможных ошибок в подходящем типе данных для каждого действия была бы серьезной задачей, и было бы действительно довольно обременительно обрабатывать каждый возможный случай или выяснять, какие части просто передать.А простое завершение результата каждого отдельного действия IO в Maybe просто приведет к ситуации, аналогичной Java, где каждая ссылка может быть нулевой.Это ничего вам не говорит, и люди часто не могут придумать разумных способов справиться с этим.

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

Это нескажем, для действия IO никогда не имеет смысла возвращать значение Maybe / Either, которое ясно указывает на возможные ошибки, просто это не всегда стоит.

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