open Okasaki open QueueSig module ImplicitQueue : Queue = struct type 'a digit = Zero | One of 'a | Two of 'a * 'a type 'a queues = Shallow of 'a digit | Deep of 'a digit * ('a * 'a) queues Lazy.t * 'a digit type 'a queue = 'a queues let empty : 'a queue = Shallow Zero let is_empty : 'a. 'a queue -> bool = function | Shallow Zero -> true | _ -> false let rec snoc : 'a. 'a queue -> 'a -> 'a queue = fun q y -> match q with | Shallow Zero -> Shallow (One y) | Shallow (One x) -> Deep (Two (x,y), lazy empty, Zero) | Deep (f, m, Zero) -> Deep (f, m, One y) | Deep (f, m, One x) -> Deep (f, lazy (snoc (!$m) (x,y)), Zero) | _ -> raise BrokenInvariant and head : 'a. 'a queue -> 'a = function | Shallow Zero -> raise EmptyStructure | Shallow (One x) -> x | Deep (One x, m, r) -> x | Deep (Two (x,y), m, r) -> x | _ -> raise BrokenInvariant and tail : 'a. 'a queue -> 'a queue = function | Shallow Zero -> raise EmptyStructure | Shallow (One x) -> empty | Deep (Two (x,y), m, r) -> Deep (One y, m, r) | Deep (One x, lazy q, r) -> if is_empty q then Shallow r else let (y,z) = head q in Deep (Two (y,z), lazy (tail q), r) | _ -> raise BrokenInvariant end |