94 lines
2.6 KiB
Groff
94 lines
2.6 KiB
Groff
#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))
|