CS 440 MP 1: Recursion - Haskell Programming Assignment, Study notes of Programming Languages

A programming assignment for cs 440 students at illinois institute of technology. The objective is to write recursive functions in haskell, using techniques such as guards and where clauses. The assignment covers functions for addition, factorial, length, take, drop, nth, append, reverse, positive, neglist, member, add, union, subset, intersection, and powerset.

Typology: Study notes

Pre 2010

Uploaded on 08/18/2009

koofers-user-u61
koofers-user-u61 🇺🇸

10 documents

1 / 8

Toggle sidebar

This page cannot be seen from the preview

Don't miss anything!

bg1
CS 440 MP 1
MP 1 Recursion
Assigned January 23, 2009
Due February 2, 2009
1 Objectives and Background
The purpose of this MP is to give you practice writing recursive functions in Haskell. You should
become familiar with lists, direct-style recursion, and tail-recursion.
Do not use list comprehensions or higher order functions. You’ll get to use them later, but you
need to have a good grasp of recursion first.
2 Techniques
To make your code readable, you may want to use one of the following techniques.
2.1 Guards
You already know from the lecture about patterns. You can make patterns more useful by adding
guards to them. If a pattern matches the input, the computer then checks the guard. If the guard
evaluates to True, the computer evaluates the body of the function; otherwise it tries another
pattern.
Example
This code doubles all the elements of a list that are odd.
1doubleodd [] =[]
2doubleodd (x:xs) =if x ‘mod‘ 2 == 1
3then x 2 : doubleodd xs
4else x : doubleodd xs
Here is another version of the function that uses guards.
1doubleodd’ [] =[]
2doubleodd’ (x:xs) |x ‘mod‘ 2 == 1=x2 : doubleodd’ xs
3|otherwise =x : doubleodd’ xs
2.2 Where Clauses
Awhere clause is similiar to let, but the definitions of variables come after the code. This encour-
ages a high-level approach to coding. The doubleodd’ function can be rewritten using where:
1doubleodd’’ [] =[]
2doubleodd’’ (x:xs) |x ‘mod‘ 2 == 1=x2 : rest
3|otherwise =x : rest
4where rest =doubleodd’’ xs
Spring 2009 Page 1 Illinois Institute of Technology
pf3
pf4
pf5
pf8

Partial preview of the text

Download CS 440 MP 1: Recursion - Haskell Programming Assignment and more Study notes Programming Languages in PDF only on Docsity!

MP 1 — Recursion

Assigned January 23, 2009 Due February 2, 2009

1 Objectives and Background

The purpose of this MP is to give you practice writing recursive functions in Haskell. You should become familiar with lists, direct-style recursion, and tail-recursion. Do not use list comprehensions or higher order functions. You’ll get to use them later, but you need to have a good grasp of recursion first.

2 Techniques

To make your code readable, you may want to use one of the following techniques.

2.1 Guards

You already know from the lecture about patterns. You can make patterns more useful by adding guards to them. If a pattern matches the input, the computer then checks the guard. If the guard evaluates to True, the computer evaluates the body of the function; otherwise it tries another pattern.

Example This code doubles all the elements of a list that are odd.

1 doubleodd [] = [] 2 doubleodd (x:xs) = if x ‘mod‘ 2 == 1 3 then x ∗ 2 : doubleodd xs 4 else x : doubleodd xs

Here is another version of the function that uses guards.

1 doubleodd’ [] = [] 2 doubleodd’ (x:xs) | x ‘mod‘ 2 == 1 = x ∗ 2 : doubleodd’ xs 3 | otherwise = x : doubleodd’ xs

2.2 Where Clauses

A where clause is similiar to let, but the definitions of variables come after the code. This encour- ages a high-level approach to coding. The doubleodd’ function can be rewritten using where:

1 doubleodd’’ [] = [] 2 doubleodd’’ (x:xs) | x ‘mod‘ 2 == 1 = x ∗ 2 : rest 3 | otherwise = x : rest 4 where rest = doubleodd’’ xs

You can put multiple definitions in a where clause, and you can put functions there too. This is particularly useful for defining auxiliary functions for tail recursion. Here is a tail-recursive function that takes the sum of a list.

1 sum x = aux x [] 2 where aux [] a = a 3 aux (x:xs) a = aux xs (a + x)

3 Problems

3.1 Plus

Write a function plus that takes numbers a and b, and returns a + b.

Example

*Main> :t plus plus :: (Num a) => a -> a -> a *Main> plus 1 2 3

Code

1 plus a b = undefined

3.2 Factorial

Write a function factorial that takes an input n and returns n!. You can assume the input is positive.

Example

*Main> :t factorial factorial :: (Num t) => t -> t *Main> factorial 42 1405006117752879898543142606244511569936384000000000

Code

1 factorial = undefined

3.3 Length

Write a function mylength that takes a list x and returns its length. There is a built-in length function already^1 , so we need to use this name instead. (^1) It should go without saying that you are not allowed to use that in your solution. But somebody always asks, so I’m saying.

Code

1 mydrop = undefined

3.6 Nth

Write a function nth that given a list x and an integer n, returns n-th element of x. You do not have to handle the case where n is greater than the length of the list. Let 0 be the index of the first element.

Example

*Main> :t nth nth :: (Num t) => t -> [t1] -> t *Main> nth 20 [2,5..] 62 *Main> nth 3 [2,4,6,8,10] 8

Code

1 nth = undefined

3.7 Append

Write a function append which takes lists [x 0 , x 1 ,... , xm] and [y 0 , y 1 ,... , yn] and returns a list [x 0 , x 1 ,... , xm, y 0 , y 1 ,... , yn].

Example

*Main> :t myappend myappend :: [t] -> [t] -> [t] *Main> myappend [2,3,4] [6,7,8] [2,3,4,6,7,8]

Code

1 myappend = undefined

3.8 Reverse

Write a function myreverse that takes a list [x 0 , x 1 ,... , xn− 1 , xn] and returns the myreversed list [xn, xn− 1 ,... , x 1 , x 0 ]. It must run in O(n) time; you will need to use tail recursion to make this work.

Example

*Main> :t myreverse myreverse :: [t] -> [t] *Main> myreverse [2,34,5] [5,34,2]

Code

1 myreverse = undefined

3.9 Positive

Write a function positive that returns the positive elements of a list. Preserve the list order.

Example

*Main> :t positive positive :: (Num a, Ord a) => [a] -> [a] *Main> positive [2,-3,4,-5,-7,8] [2,4,8]

Code

1 positive = undefined

3.10 Neglist

Write a function neglist that returns a list with everything negated.

Example

*Main> :t neglist neglist :: (Num a) => [a] -> [a] *Main> neglist [2,-3,4,-5,-7,8] [-2,3,-4,5,7,-8]

Code

1 neglist = undefined

4 Sets

We can implement sets using lists. The only difference is that a list can contain more than one copy, and in a list, order matters. We can write functions that don’t insert more than one copy of an element, and that disregard the order.

Code

1 union = undefined

4.4 Subset

Write a function subset that returns true if given x is a subset of y.

Example

*Main> :t subset subset :: (Eq t) => [t] -> [t] -> Bool *Main> subset [1,3,6,8,9] [1,3..10] False *Main> subset [1,3,9] [1,3..10] True

Code

1 subset = undefined

4.5 Intersection

Write a function intersect that returns the intersection of given sets x and y.

Example

*Main> :t intersect intersect :: (Eq a) => [a] -> [a] -> [a] *Main> intersect [1,3,6,8,9] [1,3..10] [1,3,6,8,9]

Code

1 intersect = undefined

4.6 Powerset

Write a function powerset that takes a list x and returns the powerset P(x). In case you forgot what a powerset is, it’s the set of all subsets of a particular set. So, P({}) = {{}}, P({x 1 }) = {{}, {x 1 }}, P({x 1 , x 2 }) = {{}, {x 1 }}{x 2 }, {x 1 , x 2 }}, etc. You will need a helper function addlist that adds an element to a list of sets.

Example

*Main> :t powerset powerset :: [a] -> [[a]] *Main> powerset [] [[]] *Main> powerset [2,3,4] [[],[4],[3],[3,4],[2],[2,4],[2,3],[2,3,4]]

Code

1 powerset = undefined

5 Handing In

Put all these functions in a file mp1.hs or mp1.lhs, commit it to your repository, and push it to the server. Try cloning your repository from the server to see if it has everything you expected in it. This MP is due in nine days, so that you have two weekends to finish it. Do not count on staff being able to answer email on the weekend before it is due! Get started earlier!