#lang typed-scheme ;; CHANGES ;; added annotations on all bound variables and structs ;; require typed foldl ;; made empty into a nullary function ;; added annotations on empty lists ;; added annotation on use of polymorphic functions in higher-order contexts ;; fixme -- how do we require polymorphic functions? #;(require (only (lib "list.ss") foldl)) #;(require (only "typed-list.ss" foldl)) (define-type-alias number Number) (define-type-alias boolean Boolean) (define-type-alias top Any) (define-typed-struct (a) queue ([front : (Listof a)] [rear : (Listof a)])) ; Invariants ; 1. q empty <=> (null? (queue-front q)) ; 2. elements of q = (append (queue-front q) (reverse (queue-rear q))) ;; fixme -- shouldn't have to be a function (pdefine: (a) (empty) : (queue a) (make-queue #{'() :: (Listof a)} #{'() :: (Listof a)})) (pdefine: (a) (empty? [q : (queue a)]) : boolean (null? (queue-front q))) (pdefine: (a) (insert-last [x : a] [q : (queue a)]) : (queue a) (let ([front (queue-front q)]) (if (null? front) (make-queue (cons x front) '()) (make-queue front (cons x (queue-rear q)))))) (define: insert : (All (a) (a (queue a) -> (queue a))) insert-last) (pdefine: (a) (insert* [xs : (Listof a)] [q : (queue a)]) : (queue a) ;; fixme - annoying annotation (foldl #{insert :: (a (queue a) -> (queue a))} q xs)) (pdefine: (a) (remove-first [q : (queue a)]) : (queue a) (let ([front (queue-front q)]) (if (null? front) (error 'remove-first "can't remove element from empty queue; given " q) (if (null? (cdr front)) (make-queue (reverse (queue-rear q)) '()) (make-queue (cdr front) (queue-rear q)))))) (pdefine: (a) (first+remove [q : (queue a)]) : (values a (queue a)) (let ([front (queue-front q)]) (if (null? front) (error 'remove-first "can't remove element from empty queue; given " q) (values (car front) (if (null? (cdr front)) (make-queue (reverse (queue-rear q)) '()) (make-queue (cdr front) (queue-rear q))))))) (define: -remove : (All (a) ((queue a) -> (queue a))) remove-first) (pdefine: (a) (first [q : (queue a)]) : a (when (empty? q) (error 'first "There is no first element in an empty queue; given " q)) (car (queue-front q))) (pdefine: (a) (elements: [q : (queue a)]) : (Listof a) (append (queue-front q) (reverse (queue-rear q)))) (pdefine: (a b) (fold [f : (a b -> b)] [init : b] [q : (queue a)]) : b (foldl f (foldl f init (queue-front q)) (reverse (queue-rear q)))) (pdefine: (a) (size [q : (queue a)]) : number ; NOTE: T(size) = O(n) (+ (length (queue-front q)) (length (queue-rear q)))) ;; 12 definitions checked ;; generators removed ;; TESTS (= 0 (size ((inst empty Number))))