6.1 KiB
#Lab 6: Inductive Data Types
CSci 2041: Advanced Programming Principles, Spring 2017
Due: Friday, the 24th of February, at 5.00PM.
This lab will focus on tree based inductive data types and on functions surrounding these.
##PART A:
For this part of the lab, use the following type for tree
:
type 'a tree = Leaf of 'a
| Fork of 'a * 'a tree * 'a tree
Some examples using this:
let t1 = Leaf 5
let t2 = Fork (3, Leaf 3, Fork (2, t1, t1))
let t3 = Fork ("Hello", Leaf "World", Leaf "!")
Below are a list of functions that you will need to implement on this:
1. t_size
Given an 'a tree, write a function t_size
to find the size of the tree. This function will be of the type: 'a tree -> int
.
Example:
t_size t3
gives int = 3
.
2. t_sum
Given an int tree, write a function t_sum
to find the sum of the values in the tree. The type of the function is: int tree -> int
.
Example:
let t4 = Fork (7, Fork (5, Leaf 1, Leaf 2), Fork (6, Leaf 3, Leaf 4))
t_sum t4
gives int = 28
.
3. t_charcount
Write a function t_charcount
that takes a string tree as input and count the total number of characters that the values contain. Type of the function is: string tree -> int
.
Example:
t_charcount t3 gives int = 11.
4. t_concat
Now, write a function t_concat
that will concatenate together the values of a string tree. Type of this function is: string tree -> string
.
Example:
t_concat t3 gives string = "HelloWorld!".
##PART B:
In this part, you will introduce options as well into the above tree type and handle those cases.
An example:
let t5 : string option tree = Fork (Some "a", Leaf (Some "b"), Fork (Some "c", Leaf None, Leaf (Some "d"))).
This is a tree of type string option tree
.
Write 4 new functions, similar to the ones above, but that work over trees with option
values in them
For example, t_opt_size
should count the number of values in the tree that is under the "Some" constructor.
The types are as follows:
t_opt_size : 'a option tree -> int
Example:
let t7 = (Fork (Some 1, Leaf (Some 2), Fork (Some 3, Leaf None, Leaf None)))
t_opt_size t7
gives
int = 3
t_opt_sum : int option tree -> int
Example:
t_opt_sum t7
gives int = 6
.
t_opt_charcount : string option tree -> int
Example:
let t8 = (Fork (Some "a", Leaf (Some "b"), Fork (Some "c", Leaf None, Leaf (Some "d"))))
t_opt_charcount t8
gives
int = 4
t_opt_concat : string option tree -> string
Example:
t_opt_concat t8
gives
string = "abcd"
##PART C:
In class, function tfold
with type ('a -> 'b) -> ('a -> 'b -> 'b -> 'b) -> 'a tree -> 'b
was introduced. Here is the function:
let rec tfold (l:'a -> 'b) (f:'a -> 'b -> 'b -> 'b) (t:'a tree) : 'b =
match t with
| Leaf v -> l v
| Fork (v, t1, t2) -> f v (tfold l f t1) (tfold l f t2)
The next set of questions will require you to write all the questions in PART A and PART B using tfold and without using recursionss. Name and the type are as follows:
1) tf_size : 'a tree -> int
2) tf_sum : int tree -> int
3) tf_char_count : string tree -> int
4) tf_concat : string tree -> string
5) tf_opt_size : 'a option tree -> int
6) tf_opt_sum : int option tree -> int
7) tf_opt_char_count : string option tree -> int
8) tf_opt_concat : string option tree -> string
##PART D:
This is the final part of this lab. Instead of using the above tree, will we now use a tree of this type:
type 'a btree = Empty
| Node of 'a btree * 'a * 'a btree
This is a sorted tree, and will enable us to create empty trees as well as trees with size two.
Using this tree type, do the following:
bt_insert_by
Write a function bt_insert_by
that will take a comparator, an element and a btree as the input, and insert this element into the btree using the comparator to find the correct position. As the tree is sorted, the criteria to insert is as follows:
- the values in the left subtree is always less than or equal to the value of the Node.
- the values in the right subtree is always greater that the value of the Node.
The following is the type:
bt_insert_by : ('a -> 'a -> int) -> 'a -> 'a btree -> 'a btree
Example:
let t6 = Node (Node (Empty, 3, Empty), 4, Node (Empty, 5, Empty))
bt_insert_by compare 6 t6
returns
int btree = Node (Node (Empty, 3, Empty), 4, Node (Empty, 5, Node (Empty, 6, Empty)))
You can use the comparator found in the Pervasives (Pervasives.compare) module, but, ensure that you understand how it actually works, lest it inserts the element in the incorrect location.
bt_elem_by
Like in the homework, write a similar function bt_elem_by
that will now take as inputs a function, an element and a btree, and return true if the element exists in the tree, or, false otherwise. The type of the function is:
bt_elem_by : ('a -> 'b -> bool) -> 'b -> 'a btree -> bool
Example:
let t6 = Node (Node (Empty, 3, Empty), 4, Node (Empty, 5, Empty))
bt_elem_by (=) 4 t6
returns true
bt_to_list
Create a function bt_to_list
that will take as a btree and create a list of all the values in the btree. The type of the function is 'a btree -> 'a list
.
Example: bt_to_list t6
will return
int list = [3; 4; 5]
.
btfold
Like tfold
, now create a function btfold
of the type 'b -> ('b -> 'a -> 'b -> 'b) -> 'a btree -> 'b
.
btf_elem_by
Write btf_elem_by
so that it has the same behaviour as bt_elem_by
that you wrote above but this one must not be
recursive and must instead use btfold
.
btf_to_list
Similarly, write a new function named btf_to_list
that has the same behaviour as your bt_to_list
function that you wrote above. But now use btfold
instead without recursion. Call this function btf_to_list
.
btf_insert_by
? ?
Finally, write a comment on why will using btfold
for bt_insert_by
might be difficult.