October 18 Lesson

  1. Section notes for October 18
  2. Exam
  3. Problem 2b
  4. Problem 3
  5. Homework 3
    1. Problem 1
      1. Inferring the type of A
      2. How do you compose A o A?
    2. Problem 2

Section notes for October 18

Exam

Per-problem statistics:

# 1# 2# 3# 4Total
Mean 11.8117.9411.1524.9366
Median 1219112666

Problem 2b

See official solutions for tree transformation diagrams.

With different rebalancing rules, we could reduce the number of tree transformations. Consider the size-3 subtree containing the new node. Instead of coloring the leaves black we can color the leaves red, and the root black. This coloring preserves the red-black properties.

Problem 3

  foldl f () l

Here, f () is not a call to f!

Homework 3

Problem 1

Inferring the type of A

  fun A f x x 

A is bound to a curried function. With sugar removed, the function is equivalent to

   fn(f)=>fn(x)=>f x x

which is equivalent to

  fn(f)=>fn(x)=>(f x) x  

What is the type of this expression? We will infer the types bottom-up.


  (f x)

x 's type is 'a. f 's type is 'a->'b .

  (f x) x

(f x) 's type is 'a->'c , so 'b = 'a->'c . (f x) x 's type is 'c .

So f 's type is 'a->'a->'c .

So A 's type is ('a->'a->'b)->'a->'b

How do you compose A o A?

   f o g (x) = f(g(x))

So (A o A) is

    fn(f)=>fn(x)=> ((fn(f)=>fn(x)=>f x x) f) x x

To make our lives easier, use a different, but equivalent for these purposes, evaluation order from the ones used by SML. Applying f to the inner occurrence of A:

    fn(f)=>fn(x)=> (fn(x)=>f x x) x x

Applying x to the resulting anonymous function:

    fn(f)=>fn(x)=> (f x x) x

Removing the parens:

    fn(f)=>fn(x)=> f x x x

One can generalize this procedure to the problem

    A o F

Where F is a function of the form

   fn(f)=>f(x)=> Y

The inductive proof is based on substituting A^n for F.

Problem 2

The most common problem with the AST evaluator was having an incorrect implementation of substitute(id, what, target), or how to use it.

The easiest way to implement substitute() is to recursively subsitute() down the tree, except possibly for new variable bindings (e.g., function definition or let). If the new variable is named id, the substitution should not modify that subtree, since the new binding shadows the old. Otherwise, the new variable is named something else and doesn't shadow the substitution, so the substitution is applied.