Spec-Zone.ru › Haskell 9

6.19.4. Утверждения

Если вы хотите использовать утверждения в вашем стандартном коде Haskell, вы можете определить функцию, как следующую:

assert :: Bool -> a -> a
assert False x = error "assertion failed!"
assert _     x = x

которая работает, но предоставляет не очень полезное сообщение об ошибке — утверждение не выполнено, но какое и где?

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

GHC предлагает здесь помощь, выполняя всё это за вас. Для каждого использования assert в исходном коде пользователя:

kelvinToC :: Double -> Double
kelvinToC k = assert (k >= 0.0) (k-273.15)

GHC перепишет это, включив также местоположение источника, где было сделано утверждение,

assert pred val ==> assertError "Main.hs|15" pred val

Переписывание выполняется только компилятором, когда он обнаруживает применения Control.Exception.assert, поэтому вы всё ещё можете определить и использовать свои собственные версии assert, если захотите. В противном случае импортируйте Control.Exception для использования assert в вашем коде.

GHC игнорирует утверждения, когда оптимизация включена с флагом -O. То есть выражения вида assert pred e будут переписаны в e. Также можно отключить утверждения, используя опцию -fignore-asserts. Опция -fno-ignore-asserts позволяет включить утверждения даже при включённой оптимизации.

Ошибки утверждений можно перехватить. См. документацию для библиотеки Control.Exception для подробностей.

6.19.5. Макрос __GLASGOW_HASKELL_ASSERTS_IGNORED__ CPP

Когда код компилируется с игнорированием утверждений (с использованием -fignore-asserts или -O), макрос CPP __GLASGOW_HASKELL_ASSERTS_IGNORED__ будет определён. Это можно использовать для условной компиляции собственных пользовательских функций, похожих на утверждения. Например:

checkedAdd :: Word -> Word -> Word
#ifdef __GLASGOW_HASKELL_ASSERTS_IGNORED__
  checkedAdd lhs rhs = lhs + rhs
#else
  checkedAdd lhs rhs
    | res < lhs || res < rhs = raise OverflowException
    | otherwise              = res
    where res = lhs + rhs
#endif

© 2002–2007 The University Court of the University of Glasgow. All rights reserved.
Licensed under the Glasgow Haskell Compiler License.
https://downloads.haskell.org/~ghc/9.12.1/docs/users_guide/exts/assert.html

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API