Exceptions in ML (See Section 2.8, page 43, in Introduction to Standard ML) * An example - exception Head; (* exception binding *) > exception Head; - fun head(nil) = raise Head | head(x::l) = x; > val head = fn : 'a list -> 'a - head [1,2,3]; > 1 : int - head []; > Failure: Head * What if we did not declare Head to be an exception? * What if we did not raise an exception in head(nil)? * Exceptions are useful only if you have exception handlers: - fun head2 l = head(l) handle Head => 0; (* exception handler *) > val head2 = fn : int list->int - head2 [1,2,3]; > 1 : int - head2(nil); > 0 : int * In general, the expression e handle exn => e1 is evaluated as follows: 1. evaluate e; 2. if it returns a value v, then it's the value of the whole expression; 3. if it raises the exception exn, then return the value of e1; 4. if it raises any other exception, then raise that exception. * e and e1 must have the same type. * Handling multiple exceptions: - exception Mod31 and Mod32; - fun foo n = if n mod 3 = 1 then raise Mod31 else if n mod 3 = 2 then raise mod32 else 17 div n; - fun bar m = foo(m) handle Mod31 => 1 | Mod32 => 2 | Div => 99999;