The nasty thing is, that the library has to define <math>n^2</math> instances for <math>n</math> exceptions.

−

* [[Darcs]] [http://code.haskell.org/explicit-exception/ repository]

+

Even worse, if your application imports package A and package B with their sets of exception types, you have to make the exception types of A instances of the exception classes of B and vice versa, and these are orphan instances.

+

Thus I propose that a library does not export any exception type, but only its exception classes.

+

It can define exception types internally for catching exceptions itself.

+

This way your application would define the exception types for the exceptions it wants to catch and define instances against all exception classes that occur in the called functions.

== See also ==

== See also ==

Line 124:

Line 254:

* [[Error]]

* [[Error]]

* [[Error vs. Exception]]

* [[Error vs. Exception]]

+

* {{HackagePackage|id=control-monad-exception}} (reduces the number of type class instances by some type extensions)

[[Category:Glossary]]

[[Category:Glossary]]

Latest revision as of 13:26, 5 January 2012

An exception denotes an unpredictable situation at runtime, like "out of disk storage", "read protected file", "user removed disk while reading", "syntax error in user input".
These are situation which occur relatively seldom and thus their immediate handling would clutter the code which should describe the regular processing.
Since exceptions must be expected at runtime there are also mechanisms for (selectively) handling them.

Contents

The great thing about Haskell is that it is not necessary to hard-wire the exception handling into the language.
Everything is already there to implement the definition and handling of exceptions nicely.

See the implementation in

Control.Monad.Error

(and please, excuse the misleading name for now).

There is an old dispute between C++ programmers on whether exceptions or error return codes are the right way.
Also Niklaus Wirth considered exceptions to be the reincarnation of GOTO and thus omitted them in his languages.
Haskell solves the problem a diplomatic way:
Functions return error codes, but the handling of error codes does not uglify the calling code.

First we implement exception handling for non-monadic functions.
Since no IO functions are involved, we still cannot handle exceptional situations induced from outside the world,
but we can handle situations where it is unacceptable for the caller to check a priori whether the call can succeed.

Defining exception types as a sum of "this particular exception" and
"another exception" lets us compose concrete types that can carry a
certain set of exceptions on the fly. This is very similar to switching
from particular monads to monad transformers. Thanks to the type class
approach the order of composition needs not to be fixed by the throwing
function but is determined by the order of catching. We even do not have
to fix the nested exception type fully when catching an exception. It is

The nasty thing is, that the library has to define n2 instances for n exceptions.
Even worse, if your application imports package A and package B with their sets of exception types, you have to make the exception types of A instances of the exception classes of B and vice versa, and these are orphan instances.
Thus I propose that a library does not export any exception type, but only its exception classes.
It can define exception types internally for catching exceptions itself.
This way your application would define the exception types for the exceptions it wants to catch and define instances against all exception classes that occur in the called functions.