【SICP练习】101 练习2.77-2.78
練習2.77
我們首先來看看題目中描述的問題,當Louis Reasoner試著求值(magnitude z)時,程序中不斷的尋找。一開始是通過apply-generic、而后是map,最后是get。這三個函數在書中都有很好的解釋,我自知才疏學淺就不介紹了。最后一步的get中,最后由于找不到匹配的參數而返回了#f。而在Alyssa的程序中則不然。具體請看代碼。
(define (install-rectangular-package)(define (real-part z) (car z))(define (imag-part z) (cdr z))(define (make-from-real-imag x y) (cons x y))(define (magnitude z)(sqrt (+ (square (real-part z))(square (imag-part z)))))(define (angle z)(atan (imag-part z) (real-part z)))(define (make-from-mag-ang r a) (cons (* r (cos a)) (* r (sin a))))(define (tag x) (attach-tag 'rectangular x))(put 'real-part '(rectangular) real-part)(put 'imag-part '(rectangular) imag-part)(put 'magnitude '(rectangular) magnitude)(put 'angle '(rectangular) angle)(put 'make-from-real-imag 'rectangular (lambda (x y) (tag (make-from-real-imag x y))))(put 'make-from-mag-ang 'rectangular (lambda (r a) (tag (make-from-mag-ang r a)))) 'done)(define (make-from-real-imag x y)((get 'make-from-real-imag 'rectangular) x y))(define (install-polar-package)(define (magnitude z) (car z))(define (angle z) (cdr z))(define (make-from-mag-ang r a) (cons r a))(define (real-part z)(* (magnitude z) (cos (angle z))))(define (imag-part z)(* (magnitude z) (sin (angle z))))(define (make-from-real-imag x y) (cons (sqrt (+ (square x) (square y)))(atan y x)))(define (tag x) (attach-tag 'polar x))(put 'real-part '(polar) real-part)(put 'imag-part '(polar) imag-part)(put 'magnitude '(polar) magnitude)(put 'angle '(polar) angle)(put 'make-from-real-imag 'polar(lambda (x y) (tag (make-from-real-imag x y))))(put 'make-from-mag-ang 'polar (lambda (r a) (tag (make-from-mag-ang r a)))) 'done)(define (make-from-mag-ang r a) ((get 'make-from-mag-ang 'polar) r a))apply-generic 函數:
(define (apply-generic op . args)(let ((type-tags (map type-tag args)))(let ((proc (get op type-tags)))(if proc(apply proc (map contents args))(error "No method for these types -- APPLY-GENERIC" (list op type-tags))))))magnitude 、 angle 等四個通用選擇器:
(define (real-part z) (apply-generic 'real-part z)) (define (imag-part z) (apply-generic 'imag-part z)) (define (magnitude z) (apply-generic 'magnitude z)) (define (angle z) (apply-generic 'angle z))復數包:
(define (install-complex-package)(define (make-from-real-imag x y)((get 'make-from-real-imag 'rectangular) x y))(define (make-from-mag-ang r a)((get 'make-from-mag-ang 'polar) r a))(define (add-complex z1 z2)(make-from-real-imag (+ (real-part z1) (real-part z2))(+ (imag-part z1) (imag-part z2))))(define (sub-complex z1 z2)(make-from-real-imag (- (real-part z1) (real-part z2))(- (imag-part z1) (imag-part z2))))(define (mul-complex z1 z2)(make-from-mag-ang (* (magnitude z1) (magnitude z2))(+ (angle z1) (angle z2))))(define (div-complex z1 z2)(make-from-mag-ang (/ (magnitude z1) (magnitude z2))(- (angle z1) (angle z2))))(define (tag z)(attach-tag 'complex z))(put 'add '(complex complex)(lambda (z1 z2)(tag (add-complex z1 z2))))(put 'sub '(complex complex)(lambda (z1 z2)(tag (sub-complex z1 z2))))(put 'mul '(complex complex)(lambda (z1 z2)(tag (mul-complex z1 z2))))(put 'div '(complex complex)(lambda (z1 z2)(tag (div-complex z1 z2))))(put 'make-from-real-imag 'complex(lambda (x y)(tag (make-from-real-imag x y))))(put 'make-from-mag-ang 'complex(lambda (x y)(tag (make-from-mag-ang x y)))) 'done)(define (make-complex-from-real-imag x y)((get 'make-from-real-imag 'complex) x y)) (define (make-complex-from-mag-ang r a) ((get 'make-from-mag-ang 'complex) r a))put 函數和 get 函數:
(define operation-table (make-table)) (define get (operation-table 'lookup-proc)) (define put (operation-table 'insert-proc!))標識(tag)處理函數:
(define (attach-tag type-tag contents)(cons type-tag contents))(define (type-tag datum)(if (pair? datum)(car datum)(error "Bad tagged datum -- TYPE-TAG" datum)))(define (contents datum)(if (pair? datum)(cdr datum)(error "Bad tagged datum -- CONTENTS" datum))) (install-rectangular-package) (install-polar-package) (install-complex-package)修改過的復數包:
(define (install-complex-package)(define (make-from-real-imag x y)((get 'make-from-real-imag 'rectangular) x y))(define (make-from-mag-ang r a)((get 'make-from-mag-ang 'polar) r a))(define (add-complex z1 z2)(make-from-real-imag (+ (real-part z1) (real-part z2))(+ (imag-part z1) (imag-part z2))))(define (sub-complex z1 z2)(make-from-real-imag (- (real-part z1) (real-part z2))(- (imag-part z1) (imag-part z2))))(define (mul-complex z1 z2)(make-from-mag-ang (* (magnitude z1) (magnitude z2))(+ (angle z1) (angle z2))))(define (div-complex z1 z2)(make-from-mag-ang (/ (magnitude z1) (magnitude z2))(- (angle z1) (angle z2))))(define (tag z)(attach-tag 'complex z))(put 'add '(complex complex)(lambda (z1 z2)(tag (add-complex z1 z2))))(put 'sub '(complex complex)(lambda (z1 z2)(tag (sub-complex z1 z2))))(put 'mul '(complex complex)(lambda (z1 z2)(tag (mul-complex z1 z2))))(put 'div '(complex complex)(lambda (z1 z2)(tag (div-complex z1 z2))))(put 'make-from-real-imag 'complex(lambda (x y)(tag (make-from-real-imag x y))))(put 'make-from-mag-ang 'complex(lambda (r a)(tag (make-from-mag-ang r a))))(put 'real-part '(complex) real-part)(put 'imag-part '(complex) imag-part)(put 'magnitude '(complex) magnitude)(put 'angle '(complex) angle) 'done) (define (make-complex-from-real-imag x y)((get 'make-from-real-imag 'complex) x y)) (define (make-complex-from-mag-ang r a)((get 'make-from-mag-ang 'complex) r a))練習2.78
這道題要求我們修改type-tag、contents和attach-tag的定義使我們的通用算術系統可以利用Scheme的內部類型系統。也就是說將一個數字傳遞給make-scheme-number后返回的是scheme-number . 1(此處傳入的是1)。更改之后的則不需要scheme-number這一部分了。
(define (attach-tag type-tag contents)(if (number? contents)contents(cons type-tag contents))) (define (type-tag datum)(cond ((number? datum)‘scheme-number)((pair? datum)(car datum))(else (error “Bad tagged datum – TYPE-TAG” datum)))) (define (contents datum)(cond ((number? datum)datum)((pair? datum)(cdr datum))(else(error “Bad tagged datum – CONTENT” datum)))install-scheme-number-package相關代碼在書中第129頁代碼,這里load一下即可。
(install-scheme-number-package) ;Value: done (define ten (make-scheme-number 10)) ;Value: ten ten ;Value: 10 (contents ten) ;Value: 10 (type-tag ten) ;Value: scheme-number (add ten ten) ;Value: 20感謝訪問,希望對您有所幫助。 歡迎關注或收藏、評論或點贊。
為使本文得到斧正和提問,轉載請注明出處:
http://blog.csdn.net/nomasp
版權聲明:本文為 NoMasp柯于旺 原創文章,如需轉載請聯系本人。
轉載于:https://www.cnblogs.com/NoMasp/p/4786118.html
總結
以上是生活随笔為你收集整理的【SICP练习】101 练习2.77-2.78的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: PLSQL设置显示的字符集及PLSQL的
- 下一篇: 基于Erlang的并发程序简要