Fall 2024 Haskell Exam

Problem 1

Write pure function titleCase that accepts a String containing words separated by whitespace. It returns a string in which the first letter of each word is capitalized. For example:

GHCI
> titleCase "best run yet"
"Best Run Yet"
> titleCase "the 1 that got away"
"The 1 That Got Away"

Problem 2

Write pure function shrink that accepts a list of Int pairs. Each pair is a lower and upper bound. It returns a new list in which the lower bounds have been incremented and the upper bounds have been decremented. Bounds that are no longer valid are removed. For example:

GHCI
> shrink [(1, 10), (5, 6)]
[(2, 9)]
> shrink [(13, 13)]
[]

After incrementing and decrementing, (5, 6) becomes (6, 5) and (13, 13) becomes (14, 12). Neither is valid, so they are not in the returned lists.

Problem 3

Write a main function that accepts a collection of strings as command-line arguments. It prints the three longest strings from longest to shortest, each on its own line. For example:

$ runhaskell longest3.hs While the crisis lasted, people loved one another.
another.
lasted,
people

Assume there are no ties in the top three.

Problem 4

Write some types and functions for tracking a mobile device's orientation.

Define two new types: Orientation that has variants Portrait and Landscape; and Rotation that has variants Angle90, Angle180, and Angle270. Make both types able to be shown and compared for equality.

Define function rotate that accepts an Orientation and a Rotation. Have it return the new orientation after that rotation has been applied.

Define function rotateLots that accepts an Orientation and a list of Rotation. Have it return the new orientation after all rotations have been applied.

> rotate Landscape Angle90
Portrait
> rotate Landscape Angle180
Landscape
> rotateLots Portrait [Angle90, Angle270]
Portrait

Problem 5

Write pure function range that accepts a pair of Int bounds. It returns a list that includes all integers from the first number through the second. The bounds are inclusive and may be increasing or decreasing. For example:

GHCI
> range (1, 5)
[1, 2, 3, 4, 5]
> range (90, 85)
[90, 89, 88, 87, 86, 85]

Write pure function fill that accepts a list of Int. It returns a new list in which the gaps between the elements has been filled in with the intermediate numbers. For example:

> fill [0, 4, 2]
[0, 1, 2, 3, 4, 3, 2]
> fill [6, 8, 0, 3]
[6, 7, 8, 7, 6, 5, 4, 3, 2, 1, 0, 1, 2, 3]

A reasonable first step is to zip the parameter list with its tail. Functions concat and range may also come in handy.

Problem 6

You want to be able to treat values of several different types as coins that you can flip to make heads-or-tails choices. Write a typeclass Coin that imposes a function named heads on its instance types. The function accepts a value of the implementing type and returns a Bool.

Make Int, String, and Bool instances. The function returns true for odd numbers, strings of odd length, and true. Otherwise it returns false.

Write also a function named choose that accepts three parameters: a coin value, a heads value, and a tails value. The last two parameters are of an arbitrary but identical type. It returns the heads value if the coin is heads and the tails value otherwise.