Ana Ramírez Chang
CS 302
Assignment 7

Midterm 1

Instructions:

Topics covered:

Question 1: [24 pts] For each of the following expressions, give the type and the value. If the expression is not well typed write "TYPE ERROR." If the value is a function, write "lambda expression." (Goal: Test students' understanding of types and values, and a warmup question before the coding questions.)

  1. [6 pts]
     let 
        n = 15
        fun plusN (x) = n + x
        n = 3
        r = plusN(5)
     in
        r + 1
     end
      
    Answer: Type: int, Value: 21
    Goal: Test understanding of scope.

  2. [6 pts]
    let 
       n = 15
       fun create_plusN (n) = 
          fn (x) => n + x
    in
       create_plusN(2)
    end
      
    Answer: Type: int -> int, Value: lambda expression
    Goal: Test understanding of function types and the fact that lambda expressions are values.

  3. [6 pts]
      fun foo (x) = x
      
    Answer:Type: 'a -> 'a, Value: lambda expression
    Goal: Test understanding of polymorphic types

  4. [6 pts]
    let
       fun bar (x) = 
          if x then 0 else 1
    in
       bar (17)
    end   
      
    Answer: Type: TYPE ERROR, Value: N/A
    Goal: Test understanding of type errors.

Question 2: [16 pts] Fill in the types in each blank:

fun pair_list_foldr f: ('c * 'd * 'b) -> 'b base: 'b list: ('c * 'd) list
   let
      let
         fun f_wrapper (pair: 'c * 'd, res_sofar: 'b) =
            let
               (fst:'c, snd:'d = pair
            in
               f(fst, snd, res_sofar)
            end
   in
      foldr f_wrapper:('c * 'd) * 'b -> 'b base list
   end


Remember foldr: ('a * 'b -> 'b) -> 'b -> 'a list -> 'b
Goal: Test understanding of polymorphic types and foldr.

Question 3: [50 pts] Use the following representation for a binary tree for this question.

datatype 'a tree = Tree of 'a * 'a tree * 'a tree | Empty

For example, the value:

var tr: int tree = Tree(3,
                        Tree(2,
                             Tree(1, Empty, Empty),
                             Tree(7, Empty, Empty)),
                        Empty)           

represents the tree:

          3
         /
        2
       / \
      1   7  
  1. [10 pts] Implement tree_flatten: 'a tree -> 'a list. tree_flatten takes a tree and returns a flattened version as a list where the order of the elements in the list reflects a depth first traversal from left to right. For example: tree_flatten tr = [1, 2, 7, 3]
    fun tree_flatten Tree(elt, Empty, Empty) = [elt]
      | tree_flatten Tree(elt, Empty, rTree) = elt::(tree_flatten rTree)
      | tree_flatten Tree(elt, lTree, Empty) = tree_flatten lTree) @ elt
      | tree_flatten Tree(elt, lTree, rTree) =
             tree_flatten lTree) @ (elt::(tree_flatten rTree))

    Goal: Test understanding of simple recursion.

  2. [10 pts] Implement tree_flatten': 'a tree -> 'a list -> 'a list. tree_flatten' takes a tree and a list, flattens the treeas in tree_flattena nd returns the resulting list with the list it took in appeneded to the end. For example, tree_flatten' tr [15, 16, 17] = [1, 2, 7, 3, 15, 16, 17]

    You may not use "@" in your implementation.
    fun tree_flatten' Tree(elt, Empty, Empty) lst = elt::lst
      | tree_flatten' Tree(elt, Empty, rTree) lst = elt::(tree_flatten' rTree lst)
      | tree_flatten' Tree(elt, lTree, Empty) lst = tree_flatten' lTree elt
      | tree_flatten' Tree(elt, lTree, rTree) lst =
             tree_flatten' lTree elt::(tree_flatten' rTree lst)

    Goal: Test ability to build a list without using "@", and ability to implement similar functionality in two ways (parts a. and b.)

  3. [20 pts] treefold: ('a * 'b -> 'b) -> 'b -> 'a tree -> 'b. treefold folds a tree into a value of type 'b based on a combination function and a base balue of they 'b. (Similar to foldr)

    For example: The function tree_sum: int tree -> int that takes an integer tree and returns the sum of all the nodes can be implemented using treefold as follows.
    	  fun tree_sum tr = 
    	     let
    		    fun combfn(elt, sum) = elt + sum
    		 in
    		    treefold combfn 0 tr
    		end
    Implement treefold so that it traverses the tree depth first from left to right (similar to the traversal in tree_flatten and tree_flatten').
    fun treefold combfn base Tree(elt, Empty, Empty) = combfn(elt, base)

      | treefold combfn base Tree(elt, lTree, Empty =
             let
                var foldedLTree = treefold combfn base lTree (optional blank)
             in
                combfn (elt, foldedLTree)
             end

      | treefold combfn base Tree(elt, Empty, rTree) =
             let
                var combinedElt = combfn(elt, base)(optional blank)
             in
                treefold combfn combinedElt rTree
             end

      | treefold combfn base Tree(elt, lTree, rTree) =
              let
                var foldedLTree = treefold combfn base lTree (optional blank)
                var combinedElt = combfn(elt, foldedLTree)(optional blank)
             in
                treefold combfn combinedElt rTree
             end

    Goal: Test ability to transfer understanding of foldr to treefold.

  4. [10 pts] Re-implement tree_flatten:'a tree -> 'a list using treefold.
    fun tree_flatten tr =
       let
          fun combfn (elt, lst) = elt::lst
       in
          treefold combfn nil tr
       end

    Goal: Test ability to use treefold, including factoring out the combination function used in tree_flatten'.