Lecture 8, July 5

The lecture notes I post serve two purposes: to remind you of the topics we discussed and to provide any interesting code examples I did during lecture. I would describe these notes as an outline, not a summary, of what I talked about during lecture. You are not expected to be able to learn the material simply from examining these notes, nor is reading these notes a reasonable substitute for attending lecture.

Our own list structures

(define-struct Num-list-Empty ())

(define-struct Num-list-Cons
  ([first : Number]
   [rest : Num-list]))

(define-type Num-list (U Num-list-Empty Num-list-Cons))

(Num-list-Cons 2 (Num-list-Cons 3 (Num-list-Cons 5 (Num-list-Empty))))



; sqr-num-list squares all the numbers in a Num-list
(: sqr-num-list (Num-list -> Num-list))
(define (sqr-num-list l)
  (cond
   [(Num-list-Empty? l) (Num-list-Empty)]
   [else (Num-list-Cons (sqr (Num-list-Cons-first l))
                        (sqr-num-list (Num-list-Cons-rest l)))]))

(define-struct My-Empty ())

(define-struct (My-Cons A)
  ([first : A]
   [rest : (My-list A)]))

(define-type (My-list A) (U My-Empty (My-Cons A)))

(: l : (Listof Number))
(define l (cons 3 (cons 4 empty)))

(: new-list : (My-list Number))
(define new-list (My-Cons 3 (My-Cons 4 (My-Empty))))
(: n : Number)
(define n 4)

(: negate : ((My-list Number) -> (My-list Number)))
(define (negate l)
  (cond
    [(My-Empty? l) (My-Empty)]
    [else (My-Cons (- (My-Cons-first l))
                   (negate (My-Cons-rest l)))]))

Polymorphic Types

(: append (All (A) (Listof A) (Listof A) -> (Listof A)))
(define (append a b)
  (cond
    [(empty? a) b]
    [else (cons (first a) (append (rest a) b))]))

(: flatten (All (A) (Listof (Listof A)) -> (Listof A)))
(define (flatten l)
  (cond
    [(empty? l) empty]
    [else (append (first l) (flatten (rest l)))]))

Higher Order Programming

(: sqr-list ((Listof Number) -> (Listof Number)))
(define (sqr-list l)
  (cond
    [(empty? l) empty]
    [else (cons (sqr (first l)) (sqr-list (rest l)))]))

(: neg-list ((Listof Number) -> (Listof Number)))
(define (neg-list l)
  (cond
    [(empty? l) empty]
    [else (cons (- (first l)) (neg-list (rest l)))]))

(: list-upcase : (Listof String) -> (Listof String))
(define (list-upcase l)
  (cond
    [(empty? l) empty]
    [else (cons (string-upcase (first l)) (list-upcase (rest l)))]))

(: str-lens : (Listof String) -> (Listof Integer))
(define (str-lens l)
  (cond
    [(empty? l) empty]
    [else (cons (string-length (first l)) (str-lens (rest l)))]))

(: apply-fun : (All (A B) (Listof A) (A -> B) -> (Listof B)))
(define (apply-fun l func)
  (cond
    [(empty? l) empty]
    [else (cons (func (first l)) (apply-fun (rest l) func))]))

; apply-fun is same as built in function map


(: evens : (Listof Integer) -> (Listof Integer))
(define (evens l)
  (cond
    [(empty? l) empty]
    [(even? (first l)) (cons (first l) (evens (rest l)))]
    [else (evens (rest l))]))

(: empties : (All (A) (Listof (Listof A)) -> (Listof (Listof A))))
(define (empties l)
  (cond
    [(empty? l) empty]
    [(empty? (first l)) (cons (first l) (empties (rest l)))]
    [else (empties (rest l))]))

(: non-empty : (All (A) (Listof (Listof A)) -> (Listof (Listof A))))
(define (non-empty l)
  (cond
    [(empty? l) empty]
    [(cons? (first l)) (cons (first l) (non-empty (rest l)))]
    [else (non-empty (rest l))]))

(: filter : (All (A) (A -> Boolean) (Listof A) -> (Listof A)))
(define (filter func l)
  (cond
    [(empty? l) empty]
    [(func (first l)) (cons (first l) (filter func (rest l)))]
    [else (filter func (rest l))]))

; this definition shadows the built in filter function

(: gt-5 : Real -> Boolean)
(define (gt-5 n)
  (> n 5))

Polymorphic Structures

The My-List example above was also a polymorphic type. The My-Cons structure was a polymorphic structure.

(define-struct (Pair A B)
  ([a : A]
   [b : B]))

(: swap : (All (A B) (-> (Pair A B) (Pair B A))))
(define (swap p)
  (Pair (Pair-b p)
        (Pair-a p)))

Functions as output

(: add2 : Number -> Number)
(define (add2 x)
  (+ x 2))

(: add3 : Number -> Number)
(define (add3 x)
  (+ x 3))

(: addn : Number -> (Number -> Number))
(define (addn n)
  (local
    {(: f (Number -> Number))
     (define (f x)
       (+ x n))}
    f))

(: add4 : Number -> Number)
(define add4 (addn 4))

(: quad-fun : Number Number Number -> (Number -> Number))
(define (quad-fun a b c)
  (local
    {(: f (Number -> Number))
     (define (f x)
       (+ (* a x x)
          (* b x)
          c))}
    f))