[Haskell-cafe] exceptions vs. Either

Fergus Henderson fjh007 at galois.com
Tue Aug 3 19:30:54 EDT 2004

On 03-Aug-2004, Alastair Reid <alastair at reid-consulting-uk.ltd.uk> wrote:
> Another approach is to use a function:
>   inContext :: String -> a -> a
> (implemented using mapException) like this:
>   inContext "evaluating expression" (eval env e)
> to transform an exception of the form:
>    error "Division by zero"
> into
>    error "Division by zero while evaluating expression"

As written, that won't work properly; you will get misleading error
messages, due to lazy evaluation.  If a division by zero exception is
thrown, it may have occurred when computing the expression e, rather
than in the function eval itself.  Furthermore, if eval returns a compound
type, this code won't catch all division by zero errors that occur while
computing eval, only those that occur while computing the top-most node.

To make it work properly, you can do something like

	class hyperSeq a where
		hyperSeq :: a -> b -> b

	inContext :: (hyperSeq a, hyperSeq b) => String -> (a -> b) -> a -> b

and then inContext can force full evaluation of the input and output,
making sure to force full evaluation of the input _before_
invoking mapException:

	inContext msg fn input =
		hyperSeq input $
		mapException (...) $
		let output = fn input
		in hyperSeq output output

Of course then you rather completely lose lazy evaluation.
But who wants lazy evaluation, anyway? :)

Fergus J. Henderson                 |  "I have always known that the pursuit
Galois Connections, Inc.            |  of excellence is a lethal habit"
Phone: +1 503 626 6616              |     -- the last words of T. S. Garp.

More information about the Haskell-Cafe mailing list