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))
 |