Exceptions are extensible variants.
type exn
You can define your own exception with the keyword exception. This is just a constructor for exn.
exception ABadThing
exception OhNo of string
Type exn is a built-in extensible variant. It allows us to provide constructors later.
exception OhNo of string;;
exception OhNo of string
Here we created an exception called OhNo that carries type string We can create an exception now with our OhNo constructor:
OhNo "oops";;
- : exn = OhNo "oops"
Note that we now have a value of type exn! We can use the raise function to "throw" an exception:
raise (OhNo "oops")
Exception: OhNo "oops".
Called from Toploop.load_lambda in file "toplevel/toploop.ml", line 212, characters 17-27
Look at that! There's been an exception, the same way that if we were to divide by zero!
1 / 0;;
Exception: Division_by_zero.
Raised by primitive operation at unknown location
Called from Toploop.load_lambda in file "toplevel/toploop.ml", line 212, characters 17-27
Exceptions don't need to carry any data:
exception ABadThing;;
exception ABadThing
raise ABadThing;;
Exception: ABadThing.
Called from Toploop.load_lambda in file "toplevel/toploop.ml", line 212, characters 17-27
OCaml programmers are more likely to create their own exceptions than Java programmers, just because it is so easy to do so. The built in function raise has type exn -> 'a.
raise;;
- : exn -> 'a = <fun>
What's interesting is that raise has a return type of 'a. We can treat it as any type we want because it never will actually return.
let x : int = raise ABadThing;;
Exception: ABadThing.
Called from Toploop.load_lambda in file "toplevel/toploop.ml", line 212, characters 17-27
Note that the error we got here was ABadThing, not a type error. This is because the type system was okay with our work, because raise will never actually return.
OCaml provides some predefined exceptions that are used pretty often
exception Failure of stringfailwith : string -> 'aexception InvalidArgument of stringinvalid_arg : string -> 'araise (Failure "my error message")
Exception: Failure "my error message".
Called from Toploop.load_lambda in file "toplevel/toploop.ml", line 212, characters 17-27
is the same as
failwith "my error message"
Exception: Failure "my error message".
Raised at Stdlib.failwith in file "stdlib.ml", line 29, characters 17-33
Called from Toploop.load_lambda in file "toplevel/toploop.ml", line 212, characters 17-27