Fall 2023 Haskell Exam
Problem 1
An arithmetic sequence is one in which the jump between numbers is constant. Write pure function isArithmetic
that accepts a 3-tuple of Int
as its sole parameter. It returns true if and only if the sequence is arithmetic. (But note that a conditional expression is entirely unnecessary here.) For example:
> isArithmetic (0, 2, 4)
True
> isArithmetic (9, 9, 9)
True
> isArithmetic (21, 15, 9)
True
> isArithmetic (0, 7, 10)
False
Problem 2
Write pure function singles
that accepts a list of String
and Int
tuples. Each tuple names an item and how many times it occurs. The function returns a flat list in which each item occurs the specified number of times. For example:
> singles [("tear", 2), ("lock of hair", 1)]
["tear", "tear", "lock of hair"]
Builtin functions concat
and replicate
are useful here.
Problem 3
Write pure function wordogram
that reports how many times words of various lengths appear in a list of words. It accepts two parameters in the following order:
-
A list of lengths, each an
Int
-
A list of words, each a
String
It returns a list of tuples whose first element is the corresponding word length and whose second element is the number of words of that length in the list. For example:
> wordogram [5, 2, 1, 3, 6] ["Art", "is", "a", "lie", "that", "makes", "us", "realize", "truth"]
[(5, 2), (2, 2), (1, 1), (3, 2), (6, 0)]
There are two 5-letters words: makes and truth. There are two 2-letters words: is and us. There is one 1-letter word: a. There are two 3-letters words: Art and lie. There are zero 6-letter words.
Problem 4
Some data is circular, like colors on a color wheel and directions on a compass. Using data
, define Color
and Direction
with the variants shown on these wheels:
Have the types implement Show
and Eq
.
The variants on these wheels have opposites. We'd like a uniform way of finding a variant's opposite. Define a typeclass named Opposable
that imposes a pure function named opposite
. Given a variant, it returns its opposite. Make Color
and Direction
instances of this typeclass. Then we can make calls like these:
> opposite NW
SE
> opposite E
W
> opposite Red
Green
> opposite Green
Red
Problem 5
Write a main
that reads in the file whose path is passed as a command line argument. The file contains a bunch of numbers, one per line. Print the five biggest numbers to standard output in descending order. For example, suppose a file has these lines:
234.28
4568.52
567.98
3324.63
45.34
905.07
294.35
2456.56
When given this file, your program produces this output:
4568.52
3324.63
2456.56
905.07
567.98
Problem 6
A file on disk is a one-dimensional sequence of characters. For example:
I'm still trying everything\nTo keep you looking at me\n
The sequence is indexed by a single 0-based Int
. The first m
is at index 2, the first linefeed is at index 27, and the T
at index 28.
Such sequences are often read and split into a list of lines. For example:
["I'm still trying everything", "To keep you looking at me"]
Characters in the two-dimensional lines list are indexed by a row and column, both 0-based. Write pure function indexToPair
that accepts a one-dimensional index as an Int
and a list of String
. The function returns the row and column at which the character occurs—as a tuple. For example, these two calls find the row-column pairs of the first m
, the first linefeed, and T
:
> indexToPair 2 ["I'm still trying everything", "To keep you looking at me"]
Just (0, 2)
> indexToPair 27 ["I'm still trying everything", "To keep you looking at me"]
Just (0, 27)
> indexToPair 28 ["I'm still trying everything", "To keep you looking at me"]
Just (1, 0)
Assume each line ends in a linefeed character (\n
). Return the tuple as a Maybe
that is Nothing
if the index isn't valid. Writing a recursive helper function is fair game and probably a good idea.