Due: Fri. Oct 12 11:59 PM (see
submission
guidelines below)
This one is due later than typical since you have an algorithms test.
But you still want to do this right away since the next homework is
still due next week.
The goals of this homework are:
- Get used to Haskell and Hugs
- Think functionally. In particular, this means getting used
to
recursion.
Problem 0
Download and install a Haskell compiler. You should
probably try to run a few of the sample programs that come with hugs,
just to get familiar with the system - the linux version has sample
programs in the demos directory, and I assume the same programs are
available in other versions. If you need, Daume (listed on the webpage)
has a simple walkthrough based on Hugs.
All of the programs in this assignment can be written in a few lines of
code. If you are writing a lot of code, you should probably
rethink your approach. As mentioned in class, think
functionally
and recursively! As a rough rule of thumb, if you are
spending
more than a minute to write the functions for this
assignment (excluding time to understand the problem and debug the
code), you are probably thinking
imperatively and not functionally.
As you may know, Haskell (like any language) has a large library of
predefined functions. As it would defeat the purpose of this
homework assignment, you are
not
allowed
to use any of the following:
- Predefined
functions other than the ones we discussed in class: arithmetic,
comparison, logical, and the list functions ++, head, tail, and ':'.
- List comprehension (we haven't covered this yet)
- Notational conveniences such as where,
let, case, and do
expressions (this is not a complete list). Since these lend
themselves to imperative thought, most introductory courses
(including this one) bar their use.
In this course, you are also required to include signatures for all
Haskell functions.
Problem 1A: Recursion is beautiful (50%)
Write the following functions in Haskell. You should make all functions
polymorphic (except when not possible due to problem constraints). Do
not name the functions differently (or with a different
case), since your program will be tested on this spelling.
Requirement: You must use each of these techniques at least once:
guards, pattern matching, if-then-else.
- prefix list int: return the prefix of list of size int (or
the entire list, if int is too large).
Ex: prefix "abcde" 3 = "abc"
- suffix list int: same as prefix, except that it returns the suffix
- interleave list1 list2 pad: return a list that interleaves the 2
argument lists, using pad for padding in case they don't have the same
length.
Ex: interleave "ab" "cde" 'f' =
"acbdfe" interleave [1,2] [3,4] 5 =
[1,3,2,4]
- interleave2 list1 list2: same as interleave, except that it uses
the first character of the shorter list for padding.
- interleave3 list1 list2: same as interleave, except that it wraps
around and rotates through the shorter list if the 2 lists have
different lengths.
Ex: interleave3 "abc" "efghi" = "aebfcgahbi"
Problem 1B:
Label 3 of your functions with comments stating "GUARD", "PATTERN
MATCHING", or
"IF-THEN" to show that you are following the guidelines for 1A.
Problem 2: Higher Order Functions are Powerful (40%)
Write the following functions in Haskell. This time you are required to
use higher order functions (either a function that you pass around as
an argument or the predefined ones map/filter).
- multFirst intlist: return the list containing the products of the
first and n'th elements of intlist (for n=2..length(intlist)).
Ex: multFirst [2,3,4,5] = [6,8,10]
- odds intlist: return the odd integers in intlist. Note that you
can use the predefined [prefix] function mod if you want.
Ex: odds [1,5,6,4,9,3] = [1,5,9,3]
- cyclicn func intstart intn: return True iff func applied to
intstart at most intn times returns intstart (i.e.,
func(func(...(func(intstart))...)) = intstart, where func is applied at
most intn times.
Ex: cyclicn (\n -> (mod (n+3) 7)) 5 9 =
True cyclicn (\n -> (mod (n+3) 7)) 5 6
= False
- incsubseq intlist: return a list of all increasing subsequences
of intlist.
Ex:
incsubseq [1,5,3,4] =
[[],[1],[1,5],[1,3,4],[1,3],[1,4],[5],[3],[3,4],[4]]
Hint: We did subseq in class, which was a map using the function (x:).
What lambda-function is incsubseq a map of?
Problem 3: Semantics (10%)
We discussed 3 types of formal semantics this
semester. For each of these, write a sentence or two
indicating
whether or not it makes sense for a functional language.
Explain.
Please write these as comments at the bottom of your program, but make
sure to identify them clearly.
Submission
The programs should be submitted electronically to the
grader (see
course webpage for address), and cc'd to the instructor. All
programs
should
be in one file,
named
<firstname>_<surname>_hw5.hs.
Hints / Clarifications / Corrections
- You probably want to learn how to interpret Haskell error
messages. The most common messages (for me) are type
mismatches,
and you should learn how to interpret the message first, as tempting it
might be to change the code randomly at the line with the error.
- You will not be graded on efficiency in this course (within
reason). Save it for your algorithms course.