Introduction to Functional Programming

DAY: YYYY-MM-DD TIME: 14:00–14:01 PLACE: home




David Sands

An English (or English-Swedish, or English-X) dictionary

Completing Part I gives a 3 or a G;
Part I and Part II are both needed for a 4, 5, or VG

This exam consists of two parts:
Part I   (7 small assignments)

  • Give good enough answers for 5 assignments here and you will get a 3 or a G
  • (Points on Part II can be counted towards Part I if needed, but this is very unlikely to happen in practice.)
Part II   (2 larger assignments)

  • You do not need to solve this part if you are happy with a 3 or a G!
  • Pass Part I and one assignment of your choice here and you will get a 4
  • Pass Part I and both assignments here and you will get a 5 or a VG

Please read the following guidelines carefully:
  • Begin each assignment on a new sheet
  • Write your number on each sheet
  • Write clearly; unreadable = wrong!
  • Comments (if needed) can be given in Swedish or English
  • You can make use of the standard Haskell functions and types given in the attached list (you have to implement other functions yourself if you want to use them)
  • You do not have to import standard modules in your solutions
  • Space left intentionally non-blank

  • Good Luck!

    Part I

    You have to complete 5 out of the following 7 assignments to get a pass on the exam.


    Given the following function

    q2 :: Eq a => [a]  -> [a]
    q2 []                    = []
    q2 (x:xs) | x `elem` xs  = q2 [y | y <- xs, y /= x]
              | otherwise    = x : q2 xs

    what would the following expression give in ghci?

    q2 ( words "spam eggs chips spam")


    In this question you should assume that you have a function rainfall which computes the rainfall in Gothenburg for a given week (where weeks are numbered from 1 and upwards)

    type WeekNumber = Int
    rainfall :: WeekNumber -> Double    -- assume this function exists

    Complete the definition of the following function:

    mostRain :: WeekNumber -> Double
    mostRain n | n < 1     = 0
               | otherwise =                       -- (complete this case)

    such that mostRain n (when n > 0) gives the amount of rain in the rainiest week from week 1 up to and including week n.

    For example, suppose that the rainfall in week 3 is 20.5 (rainfall 3 == 20.5). Now if week number 3 is the rainiest of the first 50 weeks, then mostRain 50 == 20.5.

    Your solution must be recursive. Solutions that do not use recursion will be considered incorrect.

    Hint: The function max may be useful. Note that you do not have to provide a definition for the function rainfall.


    The following datatypes are used to represent a hand of cards:

    data Suit = Hearts | Clubs | Diamonds | Spades
      deriving Eq
    data Rank = Numeric Int | Jack | Queen | King | Ace
      deriving Eq
    data Card = NormalCard Rank Suit | Joker    -- different from lab 2
      deriving Eq

    Define a function

    countAces:: [Card] -> Int

    where countAces returns the number of cards in the given hand which are either aces or jokers. So for example, if there are three aces and two jokers in the hand, the answer will be five.


    Given the following data type for arithmetic expressions:

    data Expr = Num Double | BinOp Op Expr Expr
     deriving (Eq,Show)
    data Op = Add | Mul
      deriving (Eq,Show)

    Define a function

    countOp :: Op -> Expr -> Int

    which counts the number of occurrences of a given operator in an expression. For example, the expression representing 1 + 2 + 3 * 4 is

    example = BinOp Add (Num 1)
                        (BinOp Add (Num 2)
                                   (BinOp Mul (Num 3)
                                              (Num 4)

    and countOp Add example would give 2.


    Write a QuickCheck property prop_map_filter that relates a list comprehension of the form:

    [f x | x <- xs, p x]

    with functions map and filter.


    Consider these two similar functions which modify every other element of their list argument:

    bf,df :: [Int] -> [Int]
    bf []       = []
    bf [x]      = [abs x]
    bf (x:y:xs) = (abs x) : y : bf xs
    df []       = []
    df [x]      = [x + 1]
    df (x:y:xs) = (x + 1) : y : df xs

    Define a more general function gf :: (a -> a) -> [a] -> [a] such that the following property holds:

    prop_gf xs = bf xs == gf abs xs
              && df xs == gf (+1) xs


    Give the definition of a quickCheck generator

    luckyList :: Gen [Integer]

    for lists of Integers, where every list generated contains at least one 7. Hint: generate two lists of numbers and use those to build one list guaranteed to contain the number 7.

    Part II

    You do not need to work on this part if you only want to get a 3 or a G (although a correct answer to part II can be used instead of a question in part I).

    If you want to get a 4 you have to pass part I and one of the following assignments.

    If you want to get a 5 or a VG, you have to do Part I, plus both of the following assignments.


    Question omitted (see old exams for examples)