[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