Higher Order Functions - Programming Languages and Compilers - Lab 2 | CS 421, Lab Reports of Computer Science

Material Type: Lab; Class: Progrmg Languages & Compilers; Subject: Computer Science; University: University of Illinois - Urbana-Champaign; Term: Summer 2008;

Typology: Lab Reports

Pre 2010

Uploaded on 03/16/2009

koofers-user-2py
koofers-user-2py 🇺🇸

10 documents

1 / 7

Toggle sidebar

This page cannot be seen from the preview

Don't miss anything!

bg1
MP 2 Higher Order Functions
CS 421 Summer 2008
Revision 1.1
Assigned June 12, 2008
Due June 20, 2008 23:59
Extension 48 hours. 20% penalty
1 Change Log
1.1 Fixed multifold example, clarified some questions.
1.0 Initial Release.
2 Objectives and Background
This MP is meant to give you practice writing and using higher order functions. The only functions you may use from
the List module for this MP are List.map,List.fold right,List.fold left,List.hd,List.tl,
and List.rev. You may, however, write helper functions.
Upon completion of this MP, you should have the following skills:
Know how to use folding and mapping style higher order functions.
Know how to apply HOFs in complex situations.
Be able to write HOFs for user-defined types.
3 Getting Started
Start with the file mp2.ml, provided in the .tgz grader package. Stubs are provided for each function mentioned
below. You can add helper functions, either outside of these function definitions or inside as local definitions. Note
that the stub contains the following at the top:
open Mp2common;;
This will include certain data types used in this MP for you.
In order to #use "mp2.ml" in an interactive OCaml session, you must first download and compile mp2common.ml
with
ocamlc -c mp2common.ml
Make sure that mp2.ml,mp2common.cmi, and mp2comon.cmo are in the same directory (you can also open
Mp2common directly in a OCaml interactive session, once you’ve compiled it). Your solution file must have the line
open Mp2common;; before your function definitions. Please don’t remove it!
The problems are designed to be done sequentially, so you can always use the solution to an earlier problem in a
later problem.
1
pf3
pf4
pf5

Partial preview of the text

Download Higher Order Functions - Programming Languages and Compilers - Lab 2 | CS 421 and more Lab Reports Computer Science in PDF only on Docsity!

MP 2 – Higher Order Functions

CS 421 – Summer 2008

Revision 1.

Assigned June 12, 2008

Due June 20, 2008 23:

Extension 48 hours. 20% penalty

1 Change Log

1.1 Fixed multifold example, clarified some questions.

1.0 Initial Release.

2 Objectives and Background

This MP is meant to give you practice writing and using higher order functions. The only functions you may use from the List module for this MP are List.map, List.fold right, List.fold left, List.hd, List.tl, and List.rev. You may, however, write helper functions. Upon completion of this MP, you should have the following skills:

  • Know how to use folding and mapping style higher order functions.
  • Know how to apply HOFs in complex situations.
  • Be able to write HOFs for user-defined types.

3 Getting Started

Start with the file mp2.ml, provided in the .tgz grader package. Stubs are provided for each function mentioned below. You can add helper functions, either outside of these function definitions or inside as local definitions. Note that the stub contains the following at the top:

open Mp2common;;

This will include certain data types used in this MP for you. In order to #use "mp2.ml" in an interactive OCaml session, you must first download and compile mp2common.ml with

ocamlc -c mp2common.ml

Make sure that mp2.ml, mp2common.cmi, and mp2comon.cmo are in the same directory (you can also open Mp2common directly in a OCaml interactive session, once you’ve compiled it). Your solution file must have the line open Mp2common;; before your function definitions. Please don’t remove it! The problems are designed to be done sequentially, so you can always use the solution to an earlier problem in a later problem.

4 Problems

4.1 Writing HOFs

Write the following higher order functions. The first three are memory tests – you can of course look them up, but you should be able to write them from memory without doing so.

  1. Write map, using only recursion (i.e., you cannot use List.map or a fold).

let rec map f lst = ... ;;

val map : (’a -> ’b) -> ’a list -> ’b list =

map (fun n -> n * 2) [1;2;3;4;5]

  • : int list = [2; 4; 6; 8; 10]
  1. Write fold right, using only recursion (i.e., you cannot use List.fold right).

let rec fold_right f lst i = ... ;;

val fold_right : (’a -> ’b -> ’b) -> ’a list -> ’b -> ’b =

fold_right (+) [1;2;3;4;5] 0 ;;

  • : int = 15
  1. Write fold left, using only recursion (i.e., you cannot use List.fold left).

let rec fold_left f i lst = ... ;;

val fold_left : (’a -> ’b -> ’a) -> ’a -> ’b list -> ’a =

fold_left (-) 0 [1;2;3;4;5] ;;

  • : int = -
  1. Write exists p lst, which checks that at least one element in a list, lst, satisfies a given predicate p. (We call this argument p, because predicates are functions that return true or false.)

let rec exists p lst = ... ;;

val exists : (’a -> bool) -> ’a list -> bool =

exists (fun x -> x <= 8) [1;1;3;5;8];;

  • : bool = true

exists (fun x -> x <= 4) [5;7;15;5;8];;

  • : bool = false
  1. Write exists fold p lst to yield the same results as exists, but using fold (i.e., without making exists fold explicitly recursive).

let exists_fold p lst = ... ;;

val exists_fold : (’a -> bool) -> ’a list -> bool =

exists_fold (fun x -> x <= 8) [1;1;3;5;8];;

  • : bool = true

exists_fold (fun x -> x <= 4) [5;7;15;5;8];;

  • : bool = false
  1. Write a function rsum lst which computes the running sum of the list lst. A running sum of a list is defined as: [x 1 ; x 2 ; x 3 ; · · · ; xn] = [0; x 1 ; x 1 + x 2 ; x 1 + x 2 + x 3 ; · · · ; x 1 + x 2 + x 3 + · · · + xn] You may use List.rev for this problem if you wish.

let rsum lst = ...

val rsum : int list -> int list =

rsum [1;2;3;4;5];;

  • : int list = [0; 1; 3; 6; 10; 15]

4.3 Writing HOFs for Tree Data Structures

Recall from the lecture that we can write functions like map and fold can work over other datatypes, such as binary trees. Mp2common already defines this type for you:

type ’a btree = Node of ’a btree (^) * ’a btree | Leaf of ’a | Empty

  1. Write a recursive function mapbtree f t that maps a function f over a tree t.

let rec mapbtree f t = ... ;;

val mapbtree : (’a -> ’b) -> ’a btree -> ’b btree =

let st1 = Node(Leaf 10, Leaf 20);;

let st2 = Node(Leaf 40, Leaf 50);;

let st3 = Node(Leaf 30, st2);;

let tree1 = Node(st1,st3);;

let tree2 = Node(st3,st1);;

tree1;;

  • : int btree = Node (Node (Leaf 10, Leaf 20), Node (Leaf 30, Node (Leaf 40, Leaf 50)))

mapbtree ( (+) 1 ) tree1;;

  • : int btree = Node (Node (Leaf 11, Leaf 21), Node (Leaf 31, Node (Leaf 41, Leaf 51)))
  1. Write a recursive function foldbtree f g t z that folds over a tree t. Given a tree of the form Empty, foldbtree returns the base case value z. Given a tree of the form Leaf(x), foldbtree returns the result of g applied to x. Given a tree of the form Node(left, right), foldbtree first computes the value of foldbtree on the left and right subtrees and applies these two results to f.

let rec foldbtree f g t z = ... ;;

val foldbtree : (’a -> ’a -> ’a) -> (’b -> ’a) -> ’b btree -> ’a -> ’a =

foldbtree (+) (fun x -> x) tree1 0;;

  • : int = 150

4.4 Using HOFs for Tree Data Structures

For this part, you may not use recursion, except that which is contained in the higher order functions you wrote above. All the solutions to these (except isSearch) are one line long. (Yours can be longer than that.)

  1. Write a function depth t which returns the depth of a tree. Let the depth of a leaf be defined as one. Let the depth of a node be the maximum of the depths of the two subtrees, plus one. The depth of an empty tree is zero.

let depth t = ... ;;

val depth : ’a btree -> int =

depth (Leaf 4);;

  • : int = 1

depth (tree1);;

  • : int = 4

  1. Write a function isBinary t that will return true if the tree is a full binary tree. A full binary tree is one where every element is either a node or a leaf.

let isBinary t = ... ;;

val isBinary : ’a btree -> bool =

isBinary tree1;;

  • : bool = true

isBinary (Node (tree1, Empty));;

  • : bool = false
  1. Write a function flip t that reverses a tree.

let flip t = ... ;;

val flip : ’a btree -> ’a btree =

flip tree1;;

  • : int btree = Node (Node (Node (Leaf 50, Leaf 40), Leaf 30), Node (Leaf 20, Leaf 10))
  1. Write a function isSearch that will return true if the tree is a search tree. A tree is a search tree if it is a leaf, it is empty, or if it is a node in which every element of the left subtree is less than every element of the right subtree (assume no duplicate elements), and if both subtrees are themselves search trees. Hint: make your own option- like type with 3 constructors, to represent an empty tree, non-search trees, and a search tree over a range. The solution to this one is not one line long.

let isSearch t = ... ;;

val isSearch : int btree -> bool =

isSearch tree1;;

  • : bool = true

isSearch tree2;;

  • : bool = false

Recall from lecture the datatype ’a labeled tree:

type ’a labeled_tree = LTreeNode of (’a (^) * ’a labeled_tree list);;

This type may be found in Mp2common.

  1. Write a recursive function foldLabTree nodeFun nilCase consFun t folds over a labeled tree t. Recall that, since this is a nested recursive definition, you should use a mutually recursive solution.

let rec foldLabTree nodeFun nilCase consFun t= ... ;; val foldLabTree : (’a -> ’b -> ’c) -> ’b -> (’c -> ’b -> ’b) -> ’a Mp2common.labeled_tree -> ’c = val foldLabList : (’a -> ’b -> ’c) -> ’b -> (’c -> ’b -> ’b) -> ’a Mp2common.labeled_tree list -> ’b =

  1. Using the function foldLabTree, but no other recursion, write the function mapLabTree f t that maps a function f over every value in every node for the tree t.

let ltree =

LTreeNode(5, [LTreeNode (3, []); LTreeNode (2, [LTreeNode (1, []); LTreeNode (7, [])]); LTreeNode (5, [])]);; val ltree : int labeled_tree = LTreeNode (5, [LTreeNode (3, []); LTreeNode (2, [LTreeNode (1, []); LTreeNode (7, [])]); LTreeNode (5, [])])

mapLabTree (fun x -> (x, "a") ltree;;

val ltree : (int (^) * string) labeled_tree = LTreeNode ((5, "a"), [LTreeNode ((3, "a"), []); LTreeNode ((2, "a"), [LTreeNode ((1, "a"), []); LTreeNode ((7, "a"), [])]); LTreeNode ((5, "a"), [])])

6 Handing In

Use the handin program on dcllnx?.ews.uiuc.edu (? being some machine number, which should not matter) as you did for MP1. See the instructions in the FAQ section of the webpage.