Solution (source code)

= Solution

The <ML exception type> `exn` contains exception packets and is an extensible datatype: an `exception` declaration introduces a fresh constructor, optionally with an argument. For example:
``
exception Empty;
exception BadIndex of int;
``
`Empty` has type `exn`, and `BadIndex` has type `int -> exn`. These packets are ordinary values which can be passed, returned or stored. `raise` propagates a packet; the resulting expression can have whatever result type its surrounding context requires, because normal evaluation does not return from the raise.

In <exception handling>, `expression handle pattern => recovery` evaluates the recovery for a matching exception packet and otherwise propagates the packet outward. The normal expression and recovery must have the same result type. Handlers are dynamically nested, and exceptions raised in the recovery are not handled again by that same handler. A variable pattern catches every packet, whereas a constructor pattern selects a particular exception. Separate fresh exception declarations create distinct identities even if their printed names coincide; exception rebinding instead aliases an existing constructor. \b[`exn` packages exceptional information; `raise` and `handle` determine its control-flow effect.]