# Queue — foundational two-list FIFO for Bend. # Publish entry for this package. Depends only on Base (does not reimplement List). # # Encoding: front + rear (rear stored reversed). Amortized O(1) enqueue/dequeue # via Queue.norm (rotate rear→front when front is empty). # Quantity: Queue is Kind(a), same convention as List/Maybe. import Base type Queue is Kind(a): Q{front: List, rear: List} # Dequeue view: head + rest queue (Kind-friendly; A & Queue is Type, not Kind(a)). type Queue.Deq is Kind(a): HD{head: A, rest: Queue} def Queue.empty(a, -A: Kind(a)) -> Queue: Q{Nil{}, Nil{}} def Queue.enqueue(a, -A: Kind(a), q: Queue, x: A) -> Queue: match q: case Q{f, r}: Q{f, x <> r} # When front is empty, reverse rear into front (and clear rear). def Queue.norm(a, -A: Kind(a), q: Queue) -> Queue: match q: case Q{f, r}: match f: case Nil{}: Q{List.reverse(a, A, r), Nil{}} case h <> t: Q{h <> t, r} def Queue.dequeue.go(a, -A: Kind(a), q: Queue) -> Maybe>: match q: case Q{f, r}: match f: case Nil{}: None{} case h <> t: Some{HD{h, Q{t, r}}} def Queue.dequeue(a, -A: Kind(a), q: Queue) -> Maybe>: Queue.dequeue.go(a, A, Queue.norm(a, A, q)) def Queue.peek.go(a, -A: Kind(a), q: Queue) -> Maybe: match q: case Q{f, r}: match f: case Nil{}: None{} case h <> t: Some{h} def Queue.peek(a, -A: Kind(a), q: Queue) -> Maybe: Queue.peek.go(a, A, Queue.norm(a, A, q)) def Queue.is_empty(a, -A: Kind(a), q: Queue) -> Bool: match q: case Q{f, r}: match f: case Nil{}: List.is_empty(a, A, r) case h <> t: False{} def Queue.length(a, -A: Kind(a), q: Queue) -> Nat: match q: case Q{f, r}: Nat.add(List.length(a, A, f), List.length(a, A, r)) # FIFO order: front ++ reverse(rear). def Queue.to_list(a, -A: Kind(a), q: Queue) -> List: match q: case Q{f, r}: List.append(a, A, f, List.reverse(a, A, r)) def Queue.from_list(a, -A: Kind(a), xs: List) -> Queue: Q{xs, Nil{}}