CS 224 Lab 0 – Getting up to speed in Haskell
Objectives
Perform the following tasks in the order given.
fact :: Integer -> Integer
gcd :: Integer -> Integer -> Integer
Observe that the function fact takes a
parameter which is an Integer and returns a value which is an
Integer. We denote the type of this function therefore as
Integer -> Integer.
Note that the function gcd takes two Integers as parameters
and returns an Integer. We will discuss later why the type for that
function is written so strangely as
Integer -> Integer -> Integer.
Take a look at the recursive definitions of these two functions.
[1,2,3] :: [Int]
['h', 'e', 'l' ,'l','o'] :: [Char]
[[1,2], [3]] :: [[Int]]
[(+), (*)] :: [Int->Int->Int]
A list with no elements is written as [] and
pronounced "nil". To add a single element x to the front of a list
xs, we write x : xs. In actuality the list [1,2,3] is
equivalent to 1 : (2 : (3 : [])).
Take a look at the definitions of the functions len and nth
which compute the length of a list and the nth value in a list.
Observe the types of these functions. The type [a] represents a list of
any type. Notice how the definitions use cases for the form of the
arguments.
Try the expressions:
len [2, 6, 12]
nth 2 [6,7,8,9]
| Assignment: Write the function member :: (Eq a) => Integer -> [a] -> Bool which returns the boolean value True or False depending on if the Integer parameter is contained in the list. member 2 [1, 2, 3, 4] => True member 5 [1, 2, 3, 4] => False Note that the specification (Eq a) indicates that the type a must be a type on which we can perform the == relation. |
| Assignment: Write the function double :: [a] -> [a] which returns a list with each member of the parameter repeated twice. double [1, 2, 3] => [1,1,2,2,3,3] |
data Shape = Rectangle Side Side
| Ellipse Radius Radius
deriving Showtype Radius = Float
type Side = Float
This says that a Shape can be either a Rectangle, where two sides are given as parameters, or an Ellipse where two radius values are provided. We then use type synonyms to specify that the Side and Radius types are each Floats. The specification "deriving Show" is just a way to let Haskell be able to print out values of this type.
If we want to create a rectangle, r1, with one side of length 2.0 and another of length 3.5 we would use:
r1= Rectangle 2.0 3.5
We now want a selector which will compute the area of a shape object. We define the function area for its behavior on each of the Shape constructors:
area :: Shape -> Float
area (Rectangle s1 s2) = s1*s2
area (Ellipse r1 r2) = pi*r1*r2
We could find the area of our rectangle r1:
area r1
Suppose we wish to define a binary
search tree. Recall that in a binary search tree, each node will
contain a value and the elements are arranged so that all elements smaller
than the node value are in the left sub-tree and all elements larger than
the node value are in the right sub-tree.
We can define the data type Bst :
data Bst a = Null | Branch a (Bst
a) (Bst a)
The tree contains some type a, and a tree
can either be empty (Null) or be a node (Branch) containing a
value of type a and two binary search trees representing the left and
right sub-trees.
| Assignment: Complete the function insert :: (Ord a) => a -> Bst a -> Bst a which inserts a value into a binary search tree in the proper position, returning the new binary search tree. Note that the specification (Ord a) indicates that the type a must be a type on which we can perform < , ==, and > relations. insert x Null = ___________________ insert x (Branch n left right) = if x < n then _______________________ else if x > n then ______________________ else ____________________________ Test your function on the Bst, testbst , which is provided in the Example0 file. |
| Assignment: Write the function deleteMin :: Bst a -> Bst a which returns a binary search tree with the smallest element removed. |