;; Die ersten drei Zeilen dieser Datei wurden von DrScheme eingefügt. Sie enthalten Metadaten ;; über die Sprachebene dieser Datei in einer Form, die DrScheme verarbeiten kann. #reader(lib "DMdA-assignments-reader.ss" "deinprogramm")((modname kapitel-12) (read-case-sensitive #f) (teachpacks ()) (deinprogramm-settings #(#f write repeating-decimal #t #t none explicit #f ()))) ; Kapitel 12 ; aktueller Kontostand (: balance rational) (define balance 90) ; vom Konto einen bestimmten Betrag abheben (: withdraw (rational -> boolean)) (check-expect (begin (withdraw 30) balance) 60) (check-expect (withdraw 100) #f) (define withdraw (lambda (amount) (if (>= balance amount) (begin (set! balance (- balance amount)) #t) #f))) ; Ein Konto ist ein Record ; (make-account b) ; wobei b eine Zahl ist, die den Kontostand darstellt. (define-record-procedures-2 account make-account account? ((account-balance set-account-balance!))) ; Geld von Konto abheben (: account-withdraw (account rational -> boolean)) ; Effekt: ; (account-withdraw a m) verändert den Kontostand von a (check-expect (let ((a (make-account 90))) (begin (account-withdraw a 30) (account-balance a))) 60) (check-expect (let ((a (make-account 90))) (begin (account-withdraw a 30) (account-withdraw a 100))) #f) (check-expect (let ((a (make-account 90))) (begin (account-withdraw a 30) (account-withdraw a 30))) #t) (define account-withdraw (lambda (acc amount) (if (>= (account-balance acc) amount) (begin (set-account-balance! acc (- (account-balance acc) amount)) #t) #f))) ; Ein Band-Mitglied ist ein Wert ; (make-band-member n i) ; wobei n eine Zeichenkette ist, die den Namen ; des Band-Mitglieds repräsentiert, und i eine ; Zeichenkette, die das Instrument des Band-Mitglieds ; repräsentiert. (define-record-procedures-2 band-member make-band-member band-member? ((band-member-name set-band-member-name!) band-member-instrument)) (: make-band-member (string string -> band-member)) ; Eine Band ist ein Wert ; (make-band n m) ; wobei n eine Zeichenkette ist, die den Namen ; der Band repräsentiert, und m eine Liste ; aus band-member-Records ist, welche die Mitglieder ; der Band darstellen. (define-record-procedures-2 band make-band band? (band-name (band-members set-band-members!))) (: make-band (string (list band-member) -> band)) (define axl (make-band-member "Axl" "vocals")) (define slash (make-band-member "Slash" "guitar")) (define steven (make-band-member "Steve Adler" "drums")) (define izzy (make-band-member "Izzy" "guitar")) (define duff (make-band-member "Duff" "bass")) (define guns (make-band "Guns N' Roses" (list axl slash izzy duff steven))) ; einer Band ein Mitglied hinzufügen (: add-band-member! (band band-member -> unspecific)) ; Effekt: ; (add-band-member! b m) fügt m zur Mitglieder-Komponente von b hinzu (define dizzy (make-band-member "Dizzy" "keyboard")) (check-expect (begin (add-band-member! guns dizzy) (first (band-members guns))) dizzy) (define add-band-member! (lambda (b m) (set-band-members! b (make-pair m (band-members b))))) ; Mitglied aus Band entfernen (: remove-band-member! (band band-member -> unspecific)) (check-expect (begin (remove-band-member! guns dizzy) (first (band-members guns))) axl) (check-expect (begin (remove-band-member! guns slash) (first (rest (band-members guns)))) izzy) ; Effekt: ; (remove-band-member! b m) entfernt m aus der Mitglieder-Komponente ; von b (define remove-band-member! (lambda (b m) (set-band-members! b (without m (band-members b))))) ; ein Element aus einer Liste entfernen (: without (%a (list %a) -> (list %a))) ; Band-Mitglied ersetzen (: replace-band-member! (band string string -> boolean)) ; Effekt: ; (replace-band-member! b i n) verändert die Mitglieder-Komponente ; von b (check-expect (begin (replace-band-member! guns "guitar" "Richard") (band-member-name (first-band-member-with-instrument guns "guitar"))) "Richard") (define replace-band-member! (lambda (b i n) (let ((m (first-band-member-with-instrument b i))) (if (equal? m #f) #f (begin (remove-band-member! b m) (add-band-member! b (make-band-member n i)) #t))))) ; Die Definitionen von ; - first-band-member-with-instrument ; - first-band-member-with-name ; - first-with ; sind Übungsaufgaben ; Mitglied einer Band ersetzen, das ein bestimmtes Instrument spielt (: replace-band-member-2! (band string string -> boolean)) ; Effekt: ; (replace-band-member-2! b i n) verändert die Namens-Komponente ; des gefundenen Mitglieds (check-expect (begin (replace-band-member-2! guns "drums" "Brain") (band-member-name (first-band-member-with-instrument guns "drums"))) "Brain") (define replace-band-member-2! (lambda (b i n) (let ((m (first-band-member-with-instrument b i))) (if (equal? m #f) #f (begin (set-band-member-name! m n) #t))))) ; Prozedur zum Abheben von einem Konto konstruieren (: make-withdraw (number -> (number -> (mixed number false)))) (check-expect (w1 30) 60) (check-expect (w1 30) 30) (check-expect (w1 40) #f) (check-expect (w2 0) 90) (define make-withdraw (lambda (balance) (lambda (amount) (if (>= balance amount) (begin (set! balance (- balance amount)) balance) #f)))) (define w1 (make-withdraw 90)) (define w2 (make-withdraw 90)) ; Ein Zeiger pointer(a) ist ein Wert ; (make-pointer v) ; wobei v ein Scheme-Wert der Sorte a ist, ; auf den der Zeiger zeigt. (define-record-procedures-2 pointer make-pointer pointer? ((pointer-ref pointer-set!))) ; Quotienten und Rest berechnen (: quotient-remainder (natural natural pointer pointer -> unspecific)) (check-expect (let ((qp (make-pointer -1)) (rp (make-pointer -1))) (begin (quotient-remainder 15 7 qp rp) (list (pointer-ref qp) (pointer-ref rp)))) (list 2 1)) (define quotient-remainder (lambda (a b quotient-pointer remainder-pointer) (begin (pointer-set! quotient-pointer (quotient a b)) (pointer-set! remainder-pointer (remainder a b)))))