with_exn : ('a -> 'b) -> 'a -> exn -> 'b
If f x evaluates to y, then with_exn f x e returns y. If f x raises Interrupt, then with_exn f x e raises Interrupt. Otherwise, f x raises an exception ex; in this case, with_exn f x e raises the exception e.
with_exn is commonly used to build functions which can fail in several places, all with the same error.
One could define dest_forall as follows:
local val err = mk_HOL_ERR "example" "dest_forall" ""
in
fun dest_forall M =
let val (c, Rand) = with_exn dest_comb M err
val {Name="!",Thy="bool",...} = with_exn dest_thy_const c err
in with_exn dest_abs Rand err
end
end