;; **************************************** ;; * Csu 211 : 2/4/2008 ;; * Lecture #11 Code ;; * Self-Referential Unions and Lists ;; **************************************** ; +----------------------------+ ; v | ;; A Train is either | ;; -- Caboose: (make-caboose) | ;; -- TCar: (make-tcar Train)------+ ;; Structure Defs (define-struct caboose ()) (define-struct tcar (train)) ;; train?: Any -> Boolean ;; Is the thing you gave me a train? (define (train? t) (or (caboose? t) (tcar? t))) (train? (make-caboose)) (train? (make-tcar (make-caboose))) (not (train? 5)) ;; Template for Functions that accept Trains #;(define (fun-for-trains t) (cond [(caboose? t) ... ] [(tcar? t) ... ;; Recursive call! (fun-for-train ... (tcar-train t) ...)])) ;; Train ;; add-wheels: Image -> Image ;; Add Wheels to the given image (define (add-wheels img) (overlay/xy (overlay/xy img 11 14 (circle 5 'solid 'blue)) -11 14 (circle 5 'solid 'blue))) ;; train->image: Train -> Image ;; Convert the given Train into a simple image (define (train->image t) (add-wheels (rectangle 40 20 'solid (cond [(caboose? t) 'red] [(tcar? t) 'black])))) ;; train->scene: Train Number Scene -> Scene ;; Add an image of the given train to the given ;; Scene... for a tcar, we need to draw the next ;; Trains into the scene too (define (train->scene t x scn) (place-image (train->image t) x 75 (cond [(caboose? t) scn] [(tcar? t) (train->scene (tcar-train t) (+ x 50) scn)]))) ;; add-car: Train CharOrSymbol -> Train ;; Add a car to the front of the given Train if the key pressed was ;; a character (not a 'release' event) (define (add-car t k) (cond [(char? k) (make-tcar t)] [else t])) ;; draw-train: Train -> Scene ;; Draw the (entire) given train into an empty-scene (define (draw-train t) (train->scene t 50 (empty-scene 600 150))) ;; Window setup (big-bang 600 150 .1 (make-caboose)) (on-redraw draw-train) (on-key-event add-car) ;; train-length: Train -> Number ;; Returns the number of cars in this Train (define (train-length t) (cond [(caboose? t) 1] [(tcar? t) (+ 1 (train-length (tcar-train t)))])) ;; train-length Tests (= (train-length (make-caboose)) 1) (= (train-length (make-tcar (make-caboose))) 2) (= (train-length (make-tcar (make-tcar (make-caboose)))) 3) ;; * * * * * * * * * * * * * * * * * * * ;; * * * * * Hand Rolled Lists * * * * * ;; * * * * * * * * * * * * * * * * * * * ; +----------------------+ ; v | ;; A my-list is either: | ;; -- my-empty | ;; -- (my-cons Any List) ----+ ;; Structure Defs (define-struct empt ()) (define-struct cns (first rest)) ;; Helper functions for Empty... (define my-empty (make-empt)) (define (my-empty? l) (empt? l)) ;; Helper functions for Cons... (define (my-cons f r) (make-cns f r)) (define (my-first c) (cns-first c)) (define (my-rest c) (cns-rest c)) (define (my-cons? l) (cns? l)) ;; Example (define list0 my-empty) (define list1 (my-cons "S" (my-cons "R" my-empty))) (define list2 (my-cons "what" (my-cons " are" (my-cons " you?" my-empty)))) ;; Template for functions of my-lists #;(define (func l) (cond [(my-empty? l) ... ] [(my-cons? l) ... (my-first l) ... (func ... (my-rest l) ...)])) ;; my-list-length: my-list -> Number ;; Calculate the length of the given my-list (define (my-list-length l) (cond [(my-empty? l) 0] [(my-cons? l) (+ 1 (my-list-length (my-rest l)))])) ;; my-list-length Tests (= (my-list-length list0) 0) (= (my-list-length list1) 2) (= (my-list-length list2) 3) ;; my-list-append: (my-list String) -> String ;; Append all the strings in the given my-list (define (my-list-append los) (cond [(my-empty? los) ""] [(my-cons? los) (string-append (my-first los) (my-list-append (my-rest los)))])) ;; my-list-append Tests (equal? (my-list-append list0) "") (equal? (my-list-append list1) "SR") (equal? (my-list-append list2) "what are you?")