signature THUNK = sig (* A 'a thunk is a lazily * evaluated expression e of type * 'a. *) type 'a thunk (* make(fn()=>e) creates a thunk * for e *) val make : (unit->'a) -> 'a thunk (* apply(t) is the value of t's expression, * which is only evaluated once *) val apply : 'a thunk -> 'a end structure Thunk :> THUNK = struct datatype 'a thunkPart = Done of 'a | Undone of unit -> 'a type 'a thunk = ('a thunkPart) ref fun make (f : unit -> 'a) : 'a thunk = ref (Undone f) fun apply (th : 'a thunk) : 'a = case !th of Done x => x | Undone f => let val ans = f() in (th := Done ans; ans) end end