(define title "More Abstraction & Parametric Contracts") (define description "") ;; --- show this: ------------------------------------------- (define WORLD-SCENE (empty-scene 100 100)) (define SNAKE-SEGMENT (circle 3 'solid 'brown)) ;; Segment = Posn ;; segment-move : Segment -> Segment ;; move a segment left by three pixels (define (segment-move s) (make-posn (- (posn-x s) 1) (posn-y s))) ;; segment-image : Segment -> Image ;; add the given segment to the "world scene" (define (segment-image s) (place-image SNAKE-SEGMENT (posn-x s) (posn-y s) WORLD-SCENE)) ;; --- make them write this: -------------------------------- ;; segments-move : [Listof Segment] -> [Listof Segment] ;; move all segments (define (segments-move.v1 s*) (cond [(empty? s*) empty] [else (cons (segment-move (first s*)) (segments-move (rest s*)))])) ;; segments-images : [Listof Segment] -> [Listof Image] ;; turn all segments into images (define (segments-image.v1 s*) (cond [(empty? s*) empty] [else (cons (segment-image (first s*)) (segments-image (rest s*)))])) ;; --- abstract like that ----------------------------------- (define (apply-all f s*) (cond [(empty? s*) empty] [else (cons (f (first s*)) (apply-all f (rest s*)))])) (define (segments-move s*) (apply-all segment-move s*)) (define (segments-image s*) (apply-all segment-image s*)) ;; TESTS: (equal? (segment-move (make-posn 10 10)) (make-posn 9 10)) (equal? (segments-move (list (make-posn 10 10) (make-posn 18 16))) (list (make-posn 9 10) (make-posn 17 16))) (equal? (segment-image (make-posn 10 10)) (place-image SNAKE-SEGMENT 10 10 WORLD-SCENE)) (equal? (segments-image (list (make-posn 10 10))) (list (place-image SNAKE-SEGMENT 10 10 WORLD-SCENE))) ;; --- now develop more examples ---------------------------- ;; [Listof Posn] -> [List Number] ;; Determines all x coordinates from the given list of Posns (define (xes l) (apply-all posn-x l)) ;; [Listof Number] -> [Listof Boolean] ;; determine for each number whether it is positive (define (positives l) (apply-all positive? l)) ;; all-5s: [Listof Number] -> [Listof Boolean] ;; determine for each number whether it is larger than 5? ;; say you have (define (greater-than-5 x) (> x 5)) (define (all-5s l) (apply-all greater-than-5 l)) ;; --- now design contract ----------------------------------- ;; apply-all : .. [Listof X] -> [Listof Y] ;; apply-all : [X -> Y] [Listof X] -> [Listof Y] ;; ---- ;; filter or tree; don't know yet. ;; ----------------------------------------------------------- ;; Quiz: ;; What is the contract for this function: (define (foo x ys) (cond [(empty? ys) empty] [else (cons (< x (first ys)) (foo x (rest ys)))])) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; N is one of: ;; -- 0 ;; -- (add1 N) ;; the predicates are: zero?, positive?; the selector is sub1 ;; Make examples. 0 = 0 (add1 0) = 1 (add1 (add1 0)) = 2 (add1 (add1 (add1 0))) = 3 ;; An AList is one of: ;; -- empty ;; -- (cons 'a AList) ;; Make examples. empty (cons 'a empty) (cons 'a (cons 'a empty)) ;; Problem 1: design a function that consumes an N (x) ;; and creates an AList of lenth x. ;; N -> AList (define (copy x) (cond [(zero? x) empty] [else (cons 'a (copy (- x 1)))])) (equal? (copy 3) (list 'a 'a 'a)) ;; Problem 2: design a function that consumes an N (x) ;; and creates all ALists. ;; N -> [Listof AList] (define (all x) (cond [(zero? x) (list empty)] [else (local ((define rest (all (sub1 x))) (define frst (first rest))) (cons (cons 'a frst) rest))])) (equal? (all 0) (list empty)) (equal? (all 1) (list (list 'a) empty)) (equal? (all 2) (list (list 'a 'a) (list 'a) empty)) ;; now abstract over the two ;; N X [N X -> X] -> Y (define (abstract n base combine) (cond [(zero? n) base] [else (combine n (abstract (sub1 n) base combine))])) (define (all.v2 x) (abstract x (list empty) add-one-a)) (define (add-one-a n l) (cons (cons 'a (first l)) l)) (equal? (all.v2 0) (list empty)) (equal? (all.v2 1) (list (list 'a) empty)) (equal? (all.v2 2) (list (list 'a 'a) (list 'a) empty)) (define (copy.v2 x) (abstract x empty add-an-a)) (define (add-an-a n l) (cons 'a l)) (equal? (copy.v2 3) '(a a a))