This is an old revision of the document!
Lab 3. Algebraic Datatype Definition
3.1 Abstract Lists
Below you will find the algebraic definition of the datatype IList
:
Void : IList Cons : Int x IList -> IList
This definition has already been implemented in Scala, below. Please copy-paste this definition in your worksheet.
trait IList case object Void extends IList case class Cons(x: Int, xs: IList) extends IList
3.1.1. Consider the following axioms for the operator isEmpty
.
isEmpty : IList -> Boolean isEmpty(Void) = true isEmpty(Cons(h,t)) = false.
Implement isEmpty
in Scala:
def isEmpty(l: IList) : Boolean = ???
3.1.2. Write down axioms for size : IList → Int
and implement the operator in Scala:
def size(l: IList) : Int = ???
3.1.3. Implement contains
which checks if an element is a member of a list.
def contains(e: Int, l: IList) : Boolean = ???
3.1.4. Implement max
which returns the largest integer from a list:
def max(l: IList) : Int = ???
3.1.5. Implement take
which returns a new list containing the first n
elements of the original list:
def take(n: Int)(l: IList) : IList = ???
3.1.6. Implement drop
which returns a new list containing the original list without the first n
elements:
def drop(n: Int)(l: IList) : IList = ???
3.1.7. Implement append
which concatenates two lists:
def append(l1: IList, l2: IList) : IList = ???
3.1.8. (!) Implement last
which returns the last element from a list:
def last(l: IList) : Int = ???
3.1.9. (!) Implement reverse
. There are two different ways to implement reverse (with direct and with tail-end recursion). Try both implementations.
def reverse(l: IList) : IList = ???
3.1.10. Implement isSorted
which checks if a list is sorted:
def isSorted(l: IList) : Boolean = ???
3.1.11. Implement merge
which merges two sorted lists:
def merge(l1: IList, l2: IList) : IList = ???
3.1.12. Implement mergeSort
which sorts a list:
def mergesort(l: IList) : IList = ???
3.2 Binary Tree
The type definition for Scala is given below. Please copy-paste this definition in your worksheet.
trait BinaryTree case object TVoid extends BinaryTree case class Node(left: BinaryTree, info: Int, right: BinaryTree) extends BinaryTree
A Binary Tree can either be a void object (equivalent to NULL in C), or a Node with its information as an Int and two other trees as children (left and right).
3.2.0. Implement leaf_node
that receives an Integer and returns a leaf with that integer as value:
def leaf_node(value : Int) : BinaryTree = ???
Being given the following BinaryTree:
val arborica = Node(leaf_node(5), 1, Node(leaf_node(4), 2, Node(leaf_node(3), 6, leaf_node(7))))
and the following print function
TBD
Implement the following methods for trees in Scala:
3.2.1. Implement mirror
that mirrors the tree structure:
def mirror(t: BinaryTree) : BinaryTree = ???
– 6. Implement the function flatten: flatten :: Tree a → List a flatten TVoid = GVoid flatten (Node l k r) = app (GenCel k (flatten l)) (flatten r) – flatten (Node l k r) = app (GenCel k (flatten l)) (flatten r)
– 7. Define list concatenation over type List a: app :: (List a) → (List a) → (List a) app GVoid GVoid = GVoid app l1 GVoid = l1 app GVoid l2 = l2 app (GenCel val pointer) l2 = GenCel val (app pointer l2)
– 8. Define the function tmap which is the Tree a correspondent to map::(a→b) → [a] → [b]. tmap:: (a→b) → (Tree a) → (Tree b) tmap f TVoid = TVoid tmap f (Node l k r) = Node (tmap f l) (f k) (tmap f r)
– 10. Define the function tfoldr: tfoldr :: (a → b → b) → b → Tree a → b tfoldr f acc TVoid = acc tfoldr f acc (Node l k r) = tfoldr f (tfoldr f (f k acc) l) r
– 11. Implement the flattening function using tfoldr: flattening :: Tree a → List a flattening (Node l k r) = tfoldr GenCel GVoid (Node l k r)