packages feed

alms-0.4.9: lib/libqueue.alms

module type QUEUE = sig
  type +`a queue qualifier `a
  exception Empty

  val emptyA   : all `a. unit -> `a queue
  val isEmptyA : all `a. `a queue -> bool * `a queue
  val sizeA    : all `a. `a queue -> int * `a queue
  val dequeueA : all `a. `a queue -> (`a * `a queue) option

  val enqueue  : all `a. `a -> `a queue -[a]> `a queue

  val empty    : all 'a. 'a queue
  val isEmpty  : all 'a. 'a queue -> bool
  val size     : all 'a. 'a queue -> int
  val first    : all 'a. 'a queue -> 'a
  val dequeue  : all 'a. 'a queue -> 'a queue
end

module Queue : QUEUE = struct
  type `a queue = `a list * `a list

  exception Empty

  let emptyA[`a] () = (Nil[`a], Nil[`a])
  let isEmptyA[`a] (q : `a queue) =
    match q with
    | (Nil, Nil) -> (true, (Nil[`a], Nil[`a]))
    | q                -> (false, q)
  let sizeA[`a] ((front, back) : `a queue) =
    let (lenf, front) = lengthA front in
    let (lenb, back)  = lengthA back in
    (lenf + lenb, (front, back))
  let dequeueA[`a] ((front, back) : `a queue) =
    match front with
    | Cons (x, xs) -> Some (x, (xs, back))
    | Nil ->
      match rev back with
      | Cons (x, xs) -> Some (x, (xs, Nil[`a]))
      | Nil -> None[`a * `a queue]

  let empty['a] = (Nil['a], Nil['a])
  let isEmpty[`a] (q : `a queue) =
    match q with
    | (Nil, Nil) -> true
    | _          -> false
  let enqueue[`a] (x : `a) ((front, back) : `a queue) =
    (front, Cons (x, back))
  let first[`a] (q : `a queue) =
    match dequeueA q with
    | Some (x, _) -> x
    | None        -> raise Empty
  let dequeue[`a] (q : `a queue) =
    match dequeueA q with
    | Some (_, q') -> q'
    | None         -> raise Empty
  let size[`a] ((front, back) : `a queue) =
    length front + length back
end