open Okasaki
open QueueSig
module BootstrappedQueue (* : Queue *) =
struct
type 'a queues = Empty | Struct of int * 'a list * 'a list Lazy.t queues * int * 'a list
type 'a queue = 'a queues
type 'a body = int * 'a list * 'a list Lazy.t queues * int * 'a list
let empty = Empty
let is_empty = function
| Empty -> true
| _ -> false
let rec checkq : 'a. 'a body -> 'a queue =
fun ((lenfm, f, m, lenr, r) as q) ->
if lenr <= lenfm
then checkf q
else checkf (lenfm+lenr, f, snoc m (lazy (List.rev r)), 0, [])
and checkf : 'a. 'a body -> 'a queue =
fun (lenfm, f, m, lenr, r) ->
match f, m with
| [], Empty -> Empty
| [], _ -> Struct (lenfm, !$(head m), tail m, lenr, r)
| _ -> Struct (lenfm, f, m, lenr, r)
and snoc : 'a. 'a queue -> 'a -> 'a queue =
fun q x ->
match q with
| Empty -> Struct (1, [x], Empty, 0, [])
| Struct (lenfm, f, m, lenr, r) ->
checkq (lenfm, f, m, lenr+1, x::r)
and head : 'a. 'a queue -> 'a = function
| Empty -> raise EmptyStructure
| Struct (lenfm, x::f', m, lenr, r) -> x
| _ -> raise BrokenInvariant
and tail : 'a. 'a queue -> 'a queue = function
| Empty -> raise EmptyStructure
| Struct (lenfm, x::f', m, lenr, r) ->
checkq (lenfm-1, f', m, lenr, r)
| _ -> raise BrokenInvariant
end
|