structure Ring = struct datatype 'a t = LINK of { prev: 'a t option ref, next: 'a t option ref, value: 'a } fun new x = let (* Grrr! Why can't I use val rec??? *) val prev = ref NONE val next = ref NONE val self = LINK { value = x, prev = prev, next = next } val () = prev := SOME self val () = next := SOME self in self end fun add (x, pred as LINK { prev=_, next=pn, value=_ }) = let val succ as LINK { prev=sp, next=_, value=_ } = valOf (!pn) val self = LINK { value = x, prev = ref (SOME pred), next = ref (SOME succ) } val () = pn := SOME self val () = sp := SOME self in self end fun remove (self as LINK { prev, next, value=_ }) = let val pred as LINK { prev=_, next=pn, value=_ } = valOf (!prev) val succ as LINK { prev=sp, next=_, value=_ } = valOf (!next) val () = pn := SOME succ val () = sp := SOME pred val () = prev := SOME self val () = next := SOME self in () end fun fold f a0 (self as LINK { prev, next, value }) = let val LINK { prev=_, next=eor, value=_ } = valOf (!prev) fun loop (l, a) = if l = eor then a else case valOf (!l) of LINK { prev=_, next=nl, value=x } => loop (nl, f (x, a)) in loop (next, f (value, a0)) end fun app f = fold (fn (l, ()) => f l) () fun get (self as LINK { prev=_, next=_, value }) = value end val sum = Ring.fold (fn (x, a) => a + x) 0 fun remove x = (print "Removing... "; Ring.remove x; print "done\n") val a = Ring.new 6 val b = MLton.Finalizable.new (Ring.add (2, a)) val () = MLton.Finalizable.addFinalizer (b, remove) val c = MLton.Finalizable.new (Ring.add (5, a)) val () = MLton.Finalizable.addFinalizer (c, remove) val () = print ("Sum: " ^ Int.toString (sum a) ^ "\n") val () = MLton.GC.collect () val () = print ("Sum: " ^ Int.toString (sum a) ^ "\n") val () = print "Ring works!\n"