Я думаю, что документы могут быть улучшены.Проблема, которую вы должны учитывать при throw
и т. П., Заключается в том, что throw
возвращает нижнее значение, которое «взрывается» (вызывает исключение) при оценке;но то, когда и когда происходит оценка, трудно контролировать из-за лени.
Например:
Prelude Control.Exception> let f n = if odd n then throw Underflow else True
Prelude Control.Exception> snd (f 1, putStrLn "this is fine")
this is fine
Возможно, это то, что вы хотите, но обычно нет.например, вместо приведенного выше кортежа вы можете получить большую структуру данных с одним взрывающимся элементом, который вызывает исключение, которое будет вызвано после того, как ваш веб-сервер вернет пользователю 200, или что-то в этом роде.
throwIO
позволяетВы можете последовательно вызывать исключение, как если бы это было другое действие ввода-вывода, поэтому его можно жестко контролировать:
Prelude Control.Exception> throwIO Underflow >> putStrLn "this is fine"
*** Exception: arithmetic underflow
... точно так же, как и print 1 >> print 2
.
Но обратите внимание, чтона самом деле вы можете заменить throwIO
на throw
, например:
Prelude Control.Exception> throw Underflow >> putStrLn "this is fine"
*** Exception: arithmetic underflow
Так как теперь значение взрыва имеет тип IO a
.На самом деле мне не понятно, почему существует throwIO
, кроме как документировать идиомуМожет быть, кто-то еще может ответить на этот вопрос.
В качестве последнего примера, это та же проблема, что и мой первый пример:
Prelude Control.Exception> return (throw Underflow) >> putStrLn "this is fine"
this is fine