Add exception-based memoizer 'exceptionMemoize' for pure open functions.

We run the open recursive function with pure cache lookup function in
the recursive position. The pure lookup function raises an exception
on missing key, which we catch in 'IO'. Once we catch a missing key
exception, we recursively compute the corresponding missing value,
before updating the cache and continuing.

Sneaky sneaky ...
Add tests for 'exceptionMemoize'.
Use 'Control.Exception.evaluate' in 'UnsafePurify'.

Replace my custom strictified 'return' with 'evaluate'. It seems this
is the point of 'evaluate', although it's kind of silly to add another
level of indirection for something so simple.