Homework 5 - Introduction to Haskell

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:
  1. Get used to Haskell and Hugs
  2. 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:
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.
  1. 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"
  2. suffix list int: same as prefix, except that it returns the suffix
  3. 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]
  4. interleave2 list1 list2: same as interleave, except that it uses the first character of the shorter list for padding.
  5. 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).
  1. 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]
  2. 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]
  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
  4. 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

  1. 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.
  2. You will not be graded on efficiency in this course (within reason).  Save it for your algorithms course.