(* fun-queue.sml * 2004 Matthew Fluet (mfluet@acm.org) * Ported to MLton threads. *) structure FunQueue : FUN_QUEUE = struct datatype 'a t = T of {front: 'a list, back: 'a list} local fun filterPrefix (xs, p) = case xs of [] => [] | y::ys => if p y then filterPrefix (ys, p) else xs fun filter (xs, p) = List.filter (not o p) xs fun filterRevAcc ((xs, zs), p) = case xs of [] => zs | y::ys => if p y then filterRevAcc ((ys, zs), p) else filterRevAcc ((ys, y::zs), p) fun filterRev (xs, p) = filterRevAcc ((xs, []), p) in fun cleanPrefix (T {front, back}, p) = (case filterPrefix (front, p) of [] => T {front = filterPrefix (List.rev(back), p), back = []} | front' => T {front = front', back = back}) fun clean (T {front, back}, p) = (case filter (front, p) of [] => T {front = filterRev (back, p), back = []} | front' => T {front = front', back = filter (back, p)}) fun cleanAndDeque (T {front, back}, p) = (case filter (front, p) of [] => (case filterRev(back, p) of [] => (NONE, T {front = [], back = []}) | x::front' => (SOME x, T {front = front', back = []})) | [x] => (SOME x, T {front = filterRev (back, p), back = []}) | x::front' => (SOME x, T {front = front', back = filter (back, p)})) end fun deque (T {front, back}) = (case front of [] => (case back of [] => NONE | l => let val l = List.rev l in case l of [] => raise Fail "FunQueue.deque:impossible" | x::front' => SOME (x, T {front = front', back = []}) end) | x::front' => SOME (x, T {front = front', back = back})) fun empty (T {front, back}) = (case front of [] => (case back of [] => true | _ => false) | _ => false) fun enque (T {front, back, ...}, x) = T {front = front, back = x::back} fun enqueAndClean (q, y, p) = clean (enque (q, y), p) fun new () = T {front = [], back = []} fun peek (T {front, back}) = (case front of [] => (case back of [] => NONE | l => let val l = List.rev l in case l of [] => raise Fail "FunQueue.peek:impossible" | x::_ => SOME x end) | x::_ => SOME x) end