#lang racket ;; 2.1 (define (normalize n d) (if (equal? (< n 0) (< d 0)) (cons (abs n) (abs d)) (cons (- (abs n)) (abs d)))) (define (make-rat n d) (let ([g (gcd n d)]) ; if they have the same sign, just take absolutes (normalize (/ n g) (/ d g)))) (define (print-rat rat) (display (car rat)) (display "/") (display (cdr rat)) (newline)) (map print-rat (map (λ (x) (apply make-rat x)) '((2 3) (1 2) (-3 4) (-100 -4) (100 -4)))) ;; 2.2 ;; we are using racket, so we could also define a structure. ;; (struct point (x y)) ;; instead we'll keep to the book and use cons cells. (define point-x car) (define point-y cdr) (define point cons) ;; the above could be replaced with ; (struct point (x y)) (define line-p1 car) (define line-p2 cdr) (define line cons) ; (struct line (p1 p2)) (define (average a b) (/ (+ a b) 2)) (define (midpoint-segment ls) (point (average (point-x (line-p1 ls)) (point-x (line-p2 ls))) (average (point-y (line-p1 ls)) (point-y (line-p2 ls))))) ;; 2.3 ;; not sure what the book means here. But I guess we can implement ;; rectangles as pairs, too, since we only need two corners really. ;; as "another representation", I guess we could store two line segments? ;; but either way the rect-p1 and rect-p2 ;; functions can be replaced very easily. ;; the area and perimeter functions do not care about their implementation. (define rect-p1 car) (define rect-p2 cdr) (define rect cons) ;; further abstraction, actually: rectangle side 1. ;; returns the length of rect's one side (define (rect-side-helper rect fun) (abs (- (fun (rect-p1 rect)) (fun (rect-p2 rect))))) (define (rect-s1 rect) (rect-side-helper rect point-x)) (define (rect-s2 rect) (rect-side-helper rect point-y)) (define (area rect) (* (rect-s1 rect) (rect-s2 rect))) (define (perimeter rect) (* 2 (+ (rect-s1 rect) (rect-s2 rect)))) ; 2.6 (define zero (lambda (f) (lambda (x) x))) (define (add-1 n) (lambda (f) (lambda (x) (f ((n f) x))))) (define one (λ (f) (λ (x) (f x)))) ;; applies f once. (define two (λ (f) (λ (x) (f (f x))))) ;(add-1 zero) ; is the same as ;(lambda (f) (lambda (x) (f ((zero f) x)))) ;(lambda (f) (lambda (x) ((add-1 zero) (((add-1 zero) f) x)))) (define (addition n1 n2) "Returns a function that takes a function f, returns: A function that takes a parameter x, applies f to x n1 + n2 times (n1 and n2 being church numerals, i.e. λfλx forms.)" (lambda (f) (lambda (x) ((n2 f) ((n1 f) x)) ))) (define (de-churchify n) ((n (λ (x) (+ x 1))) 0))