#lang racket (require "1.ss") ;; the module just above ;; implementation ;; [listof (list basic-customer? secret-info)] (define all '()) (define (find c) (define (has-c-as-key p) (id-equal? (basic-customer-id (car p)) c)) (define x (filter has-c-as-key all)) (if (pair? x) (car x) x)) (define (active? c) (define f (find c)) (pair? (find c))) (define not-active? (compose not active? basic-customer-id)) (define count 0) (define (add c) (set! all (cons (list c 'secret) all)) (set! count (+ count 1))) (define (name id) (define bc-with-id (find id)) (basic-customer-name (car bc-with-id))) (define (set-name id name) (define bc-with-id (find id)) (set-basic-customer-name! (car bc-with-id) name)) (define c0 0) ;; end of implementation (provide/contract ;; how many customers are in the db? [count natural-number/c] ;; is the customer with this id active? [active? (-> id? boolean?)] ;; what is the name of the customer with this id? [name (-> (and/c id? active?) string?)] ;; change the name of the customer with this id [set-name (->d ([id id?] [nn string?]) () [result any/c] ;; result contract #:post-cond (string=? (name id) nn))] [add (->d ([bc (and/c basic-customer? not-active?)]) () ;; A pre-post condition contract must use ;; a side-effect to express this contract ;; via post-conditions #:pre-cond (set! c0 count) [result any/c] ;; result contract #:post-cond (> count c0))])