7.13. Assertions

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 location where assert was used.

Ghc offers a helping hand here, doing all of this for you. For every use of 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 of Exception.assert, so you can still define and use your own versions of assert, should you so wish. If not, import Exception to make use assert in your code.

To have the compiler ignore uses of assert, use the compiler option -fignore-asserts. That is, expressions of the form assert pred e will be rewritten to e.

Assertion failures can be caught, see the documentation for the Exception library (Section 4.12 in Haskell Libraries) for the details.