CS 291 Assignment #1

Due Friday, January 30th (by 11:59pm)

Introduction:

The goal of this first assignment is to ensure you can all edit and evaluate Haskell functions, and to give you some practice with basic function definitions (including recursive functions).

The Assignment

  1. Define a two-argument function called jumpy. It should square its second argument, then mod the result by the first argument. (Haskell has a built-in function called mod.) Your solution should have type Integral a => a -> a -> a.
    Main> jumpy 2 1
    1
    Main> jumpy 25 4
    16
    Main> jumpy 25 5
    0
    Main> jumpy 25 6
    11
    

  2. Define a one-argument function called boundedJumpy that squares its argument and mods by 25. For full credit, your definition should simply give a name to a partial application of jumpy from above.
    Main> boundedJumpy 4
    16
    Main> boundedJumpy 5
    0
    Main> boundedJumpy 6
    11
    

  3. Define a function called maxFinder that takes two integers as inputs — a lower and upper bound. It should apply boundedJumpy at each of the values between the lower and upper bounds (inclusive) and return the largest result produced by boundedJumpy. For example, the first test below results in three calls to boundedJumpy — using 4, 5, and 6 as inputs — and returns 16 since it's the largest output produced by any of the three inputs. Your function should produce a program error if the first input is larger than the second.
    Main> :type maxFinder
    maxFinder :: Integer -> Integer -> Integer
    Main> maxFinder 4 6
    16
    Main> maxFinder 8 11
    21
    Main> maxFinder 2 100
    24
    Main> maxFinder 6 4
    
    Program error: First argument must be <= the second
    

  4. Define a two-argument function called average that returns the average of its (integer) inputs. It would be too simple, efficient, and boring to just sum the inputs and divide by two, so we won't. Instead, you should write a recursive solution that increments the first argument and decrements the second on each recursive call until they "meet in the middle". For full credit, your solution should never sum the two inputs, even in a base case. Your solution should have type (Integral a, Fractional b) => a -> a -> b — that is, it should take two integer values and return a floating point value. (You'll get lots of partial credit if your solution is just Fractional a => a -> a -> a.) Your function should produce a program error if the first input is larger than the second.
    Main> average 2 2 
    2.0
    Main> average 2 3
    2.5
    Main> average (-1) 5
    2.0
    Main> average 6 4
    
    Program error: First argument must be <= the second
    

  5. Define avgTuple, a slightly modified version of your solution to average that takes a single argument, a tuple, containing the two values to be averaged. The type of your new function should therefore be (Integral a, Fractional b) => (a,a) -> b for full credit.
    Main> avgTuple (2, 3)
    2.5
    Main> avgTuple (0, 100)
    50.0
    

  6. Define a function, any function, that has the following type:
    Main> :type foo
    foo :: (a,b) -> (a,b) -> Bool -> (a,b)
    

Submitting:

Put all of your function definitions in a single text file. Submit it by attaching your file to an E-mail to me at brichards@ups.edu. Please do not just copy and paste your solutions into the body of the E-mail!


Brad Richards, 2009