If you want to make use of assertions in your standard Haskell code, you could define a function like the following:
assert :: Bool -> a -> a assert False x = error "assertion failed!" assert _ x = x
which works, but gives you back a less than useful error message – an assertion failed, but which and where?
One way out is to define an extended
assert function which also
takes a descriptive string to include in the error message and perhaps
combine this with the use of a pre-processor which inserts the source
assert was used.
GHC offers a helping hand here, doing all of this for you. For every use
assert in the user’s source:
kelvinToC :: Double -> Double kelvinToC k = assert (k >= 0.0) (k-273.15)
GHC will rewrite this to also include the source location where the assertion was made,
assert pred val ==> assertError "Main.hs|15" pred val
The rewrite is only performed by the compiler when it spots applications
Control.Exception.assert, so you can still define and use your
own versions of
assert, should you so wish. If not, import
Control.Exception to make use
assert in your code.
GHC ignores assertions when optimisation is turned on with the
-O flag. That is, expressions of the form
assert pred e
will be rewritten to
e. You can also disable assertions using the
-fignore-asserts option. The option
allows enabling assertions even when optimisation is turned on.
Assertion failures can be caught, see the documentation for the Control.Exception library for the details.