open Okasaki open CatenableListSig open QueueBisSig module CatenableListImpl (Q : QueueBis) : CatenableList = struct type 'a cats = Empty | Struct of 'a * 'a cats Lazy.t Q.queue type 'a cat = 'a cats let empty = Empty let is_empty = function | Empty -> true | _ -> false let link xs s = match xs with | Empty -> raise BrokenInvariant | Struct (x, q) -> Struct (x, Q.snoc q s) let rec link_all q = let t = !$ (Q.head q) in let q' = Q.tail q in if Q.is_empty q' then t else link t (lazy (link_all q')) let append xs1 xs2 = match xs1, xs2 with | Empty, _ -> xs2 | _, Empty -> xs1 | _ -> link xs1 (lazy xs2) let cons x xs = append (Struct (x, Q.empty)) xs let snoc xs x = append xs (Struct (x, Q.empty)) let head = function | Empty -> raise EmptyStructure | Struct (x, _) -> x let tail = function | Empty -> raise EmptyStructure | Struct (x, q) -> if Q.is_empty q then Empty else link_all q end |