[MLton-user] Improved Exn.withEscape
Vesa Karvonen
vesa.karvonen at cs.helsinki.fi
Fri Aug 25 01:57:55 PDT 2006
This is a brief note about a minor improvement to the technique of setting
up an escape handler, as, for example, in the withEscape function in MLton's
library:
fun 'a withEscape (f: ('a -> 'b) -> 'a): 'a =
let
exception E of 'a
in
f (fn x => raise E x) handle E x => x
end
A problem with the above design is that the type of withEscape should really
be (with a well-known extension to the type system)
((Forall 'b. 'a -> 'b) -> 'a) -> 'a
That is, one should be able to escape from a context of any type. Alas,
SML's type system does not support the above type. In this case, however,
we can recover the universal quantification by redesigning the interface
as follows:
structure Exit :>
sig
type 'a t
val withLabel : ('a t -> 'a) -> 'a
val exitTo : 'a t -> 'a -> 'b
end = struct
type 'a t = 'a -> exn
fun withLabel f =
let
exception Exit of 'a
in
f Exit handle Exit v => v
end
fun exitTo t v = raise (t v)
end
Conceptually, withLabel sets up an exit (or escape) label that is passed
to the given function. During the withLabel invocation one can then
escape from the invocation by invoking exitTo with the label and a value
to return.
Here is a silly example (that doesn't make use of the extra polymorphism):
local
open Exit
in
val SOME 6 =
withLabel
(fn l =>
(app (fn x =>
if 0 = x mod 2 then
exitTo l (SOME x)
else
print (Int.toString x))
[1, 3, 5, 6, 7, 9]
; NONE))
end
More information about the MLton-user
mailing list