;; The first three lines of this file were inserted by DrRacket. They record metadata ;; about the language level of this file in a form that our tools can easily process. #reader(lib "htdp-beginner-reader.ss" "lang")((modname struct-intro-book-after) (read-case-sensitive #t) (teachpacks ()) (htdp-settings #(#t constructor repeating-decimal #f #t none #f () #f))) ;;; structs in racket ;;; i.e. aggregate data: take several pieces of data, ;;; and wrap them up together and consider it *one* thing ;;; (understanding it is comprised of several internal fields). ;;; "encapsulation" -- we put a capsule around the fields. ;; We wish to represent books, where a book has the info: ;; title, AND author, AND # of pages, AND is copyrighted? ; Data Definiton: (define-struct book (title author num-pages is-copyrighted?)) ; make-book : string, string, natural, boolean -> book ; Examples of the data (define b1 (make-book "The Cat in the Hat" "Seuss" 37 #true)) (define b0 (make-book "The Soul of Wit" "Barland" 0 #false)) ; `define-struct` actually introduces additional functions: ; a constructor ; and four getters ("selectors"). ; In this case, the constructor is named ; make-book : string, string, natural, boolean -> book ; and the getters are named ; book-title : book -> string ; book-author : book -> string ; book-num-pages : book -> natural ; book-is-copyrighted? : book -> boolean ; and a predicate ; book? : ANY -> boolean ; Design Recipe Step 3, Template: ; The template for a compound-type/struct with k fields is simply calling the k getters ; The template for a union-type with k branches is a `cond` with k question/answer pairs ; func-for-book : book -> ???? ; Return ??? (define (func-for-book a-book) (... (book-title a-book) ... (book-author a-book) ... (book-num-pages a-book) ... (book-is-copyrighted? a-book))) (book-title (make-book "The Cat in the Hat" "Seuss" 37 #true)) (book-is-copyrighted? b0) ; Don't use the java-esque b0.is-copyrighted? (b0 is-copyrighted) is-copyrighted? ; reading-time : book -> non-negative real ; The amount of time it takes the average reader to read a book (in minutes) ; (define (reading-time a-book) (* 2 (book-num-pages a-book))) (check-expect (reading-time (make-book "The Cat in the Hat" "Seuss" 37 #true)) 74) (check-expect (reading-time b0) 0) ; book->string : book -> string ; Return a string-representation of a book struct, user-friendly. (define (book->string a-book) (string-append (book-title a-book) ", by " (book-author a-book) " (" (number->string (book-num-pages a-book)) "pp)" (if (book-is-copyrighted? a-book) ", ©" ""))) (check-expect (book->string (make-book "The Cat in the Hat" "Seuss" 37 #true)) "The Cat in the Hat, by Seuss (37pp), ©") (check-expect (book->string (make-book "The Bat in the Mat" "Streuss" 1 #true)) "The Bat in the Mat, by Streuss (1pg), ©") (check-expect (book->string b0) "The Soul of Wit, by Barland (0pp)") (check-expect (enbiggen (make-book "The Cat in the Hat" "Seuss" 37 #true)) (make-book "The Cat in the Hat" "Seuss" 74 #true)) (check-expect (enbiggen (make-book "The Bat in the Mat" "Streuss" 1 #true)) (make-book "The Bat in the Mat" "Streuss" 2 #true)) (check-expect (enbiggen b0) b0) ; enbiggen : book -> book ; Return a book just like `a-book`, but with bigger text (hence, more pages). ; (define (enbiggen a-book) (make-book (book-title a-book) (book-author a-book) (* 2 (book-num-pages a-book)) (book-is-copyrighted? a-book))) ; derive-from : book string natnum -> book ; Create a brand new book, based on an original. ; The result's authoor will be the original author & the `new-author`, ; and the result has `numNewPages` added to the original. ; (define (derive-from original new-author num-new-pages) (make-book (string-append "Son of " (book-title original)) (string-append (book-author original) " & " new-author) (+ (book-num-pages original) num-new-pages) #false)) (check-expect (derive-from (make-book "The Cat in the Hat" "Seuss" 37 #true) "Baralnd" 10) (make-book "Son of The Cat in the Hat" "Seuss & Baralnd" 47 #false)) (check-expect (derive-from b0 "Banksie" 99) (make-book "Son of The Soul of Wit" "Barland & Banksie" 99 #false))