Одной из причин является денотационная семантика Haskell .
Одним из замечательных свойств (чистых) функций Haskell является их монотонность - более определенный аргумент дает более определенное значение. Это свойство очень важно, например, рассуждать о рекурсивных функциях (прочитайте статью, чтобы понять почему).
Обозначение исключения по определению является нижним, _|_
, наименьшим элементом в poset, соответствующем данному типу. Таким образом, чтобы удовлетворить требование монотонности, для любого обозначения f
функции Haskell должно выполняться следующее неравенство:
f(_|_) <= f(X)
Теперь, если бы мы могли отлавливать исключения, мы могли бы преодолеть это неравенство, «распознав» дно (перехватив исключение) и вернув более определенное значение:
f x = case catch (seq x True) (\exception -> False) of
True -> -- there was no exception
undefined
False -> -- there was an exception, return defined value
42
Вот полная рабочая демонстрация (требуется базовое-4 Control.Exception):
import Prelude hiding (catch)
import System.IO.Unsafe (unsafePerformIO)
import qualified Control.Exception as E
catch :: a -> (E.SomeException -> a) -> a
catch x h = unsafePerformIO $ E.catch (return $! x) (return . h)
f x = case catch (seq x True) (\exception -> False) of
True -> -- there was no exception
undefined
False -> -- there was an exception, return defined value
42
Другая причина, как отметил TomMD, заключается в нарушении ссылочной прозрачности. Вы можете заменить равные вещи равными и получить другой ответ. (Равно в денотационном смысле, т. Е. Они обозначают одно и то же значение, а не в ==
смысле.)
Как бы мы это сделали? Рассмотрим следующее выражение:
let x = x in x
Это бесконечная рекурсия, поэтому она никогда не возвращает нам никакой информации и поэтому обозначается также _|_
. Если бы мы могли отлавливать исключения, мы могли бы написать функцию f, такую как
f undefined = 0
f (let x = x in x) = _|_
(Последнее всегда верно для строгих функций, потому что Haskell не предоставляет средств для обнаружения непрерывных вычислений - и не может в принципе из-за проблемы остановки .)