В GHCi:
Prelude> error (error "")
*** Exception:
Prelude> (error . error) ""
*** Exception: *** Exception:
Почему первое не является вложенным исключением?
В GHCi:
Prelude> error (error "")
*** Exception:
Prelude> (error . error) ""
*** Exception: *** Exception:
Почему первое не является вложенным исключением?
error
особенный и не совсем исключительный механизм. Для реальных, улавливаемых исключений см Error
. Monad .
(\f g x -> f (g x)) error error ""
отличается от (.) error error ""
, даже если эта функция эквивалентна (.)
. Возможно, это связано с флагами оптимизации, с которыми был скомпилирован Prelude.
iterate error "" !! n
и офигенно fix error
.
error = error
и программирую соответственно.
Ответы:
Ответ заключается в том, что это (несколько удивительная) семантика неточных исключений.
Когда можно показать, что чистый код оценивает набор исключительных значений (т. Е. Значение error
или undefined
, а явно не вид исключений, сгенерированных в IO ), тогда язык разрешает возвращать любое значение этого набора. Исключительные значения в Haskell больше похожи NaN
на код с плавающей запятой, чем на исключения на основе потока управления в императивных языках.
Иногда даже для продвинутых хаскеллеров возникает такая проблема, как:
case x of
1 -> error "One"
_ -> error "Not one"
Поскольку код оценивает набор исключений, GHC может выбрать одно из них. При включенной оптимизации вы вполне можете обнаружить, что результат всегда оценивается как «Ни один».
Почему мы это делаем? Потому что в противном случае мы чрезмерно ограничили бы порядок оценки языка, например, нам пришлось бы исправить детерминированный результат для:
f (error "a") (error "b")
например, требуя, чтобы он оценивался слева направо, если присутствуют значения ошибок. Очень не-Аскелли!
Поскольку мы не хотим нарушать оптимизацию, которую можно выполнить в нашем коде только для поддержки error
, решение состоит в том, чтобы указать, что результатом является недетерминированный выбор из набора исключительных значений: неточные исключения! В некотором смысле возвращаются все исключения, и выбирается одно.
Обычно вам все равно - исключение является исключением - если вы не заботитесь о строке внутри исключения, и в этом случае использование error
для отладки сильно сбивает с толку.
Ссылки: Семантика для неточных исключений , Саймон Пейтон Джонс, Аластер Рид, Тони Хоар, Саймон Марлоу, Фергус Хендерсон. Разработка и реализация языков программирования Proc (PLDI'99), Атланта. ( PDF )
throw
) и что вы можете детерминированно генерировать исключение с помощью throwIO
.
case error "banana" of (x:xs) -> error "bonobo"
могу дать вам * Exception: bonobo
.