Midterm 2 Study Guide

You should read all the notes we have discussed starting from random numbers, and the corresponding textbook sections. These questions are here to help guide your studies, but are not meant to be exhaustive of everything you should know (though they do try to touch all the areas).

In all “coding” problems below, you must always include a type for each value/function/action you write.

  1. Be able to write random-number-generating functions of various forms, both functions that take as input a generator and return a value/generator pair as well as functions that use and update the standard generator in order to build IO value results (getManyIO in the notes is such an example). Some examples:

  2. Adapt the work of the shuffle function to write a function that given a list of values and a number n returns a random selection of n of the values from the list, without being allowed to select the same value twice.

  3. For the following typeclass/type pairs, implement the corresponding instance (i.e. how the type is an instance of that class):

  4. Be able to implement parts of a class like Fraction as described in the modules and hiding information notes.

  5. (Big problem, could ask you for parts) We want to define a class ModInt for integers modulo a number. For example the numbers “5 modulo 6” and “11 modulo 6” are actually the same. We decide to store this information via a data type data ModInt = MI Int Int where the first integer is the number and the second is the modulo. E.g. MI 5 6 would be the number described above. Write a module Modulo that provides this type with the following conditions:

  6. Implement a module for a “D&D dice”. A D&D die is specified informally with an expression like 2d8+3. This means “we roll two 8-sided dice, add the results, then add 3 to the final”. Implement a module for such dice, where the data type used is data Die = D Int Int Int, with the three integers representing in order the number of dice (2 in our example), the number of sides (8 in our example) and the extra added value at the end.

  7. Be able to implement various functions related to the Maybe type.

  8. Be able to implement the various functions for trees described in the “recursive types” notes.

  9. Have a basic understanding of the State type and how to use it to remember and update state data.

  10. Be able to define and use the fmap function that Functor provides, and to demonstrate its behavior and definition for Maybe, lists, and IO.

  11. Be able to define the basic functions that are part of Applicative, namely pure and <*>, and implement them for Maybe, lists and IO.

  12. Define the main Monad operators (return, >>=) and explain the difference between Monad and Applicative in terms of what they allow us to do. Implement the monad operators for Maybe and lists.

  13. Implement the following functions, which work with a monad m:

    sequence :: Monad m => [m a] -> m [a]
    sequence_ :: Monad m => [m a] -> m ()
    join :: Monad m => m (m a) -> m a
  14. Write a program that uses two threads, each printing its own character on the screen (say A and B) then using the Random module to pause for a random amount of time up to 1 second, before printing the character again, going on forever (so each thread is a loop).

  15. Write a program that behaves like 14 above, except that the two threads use an MVar to communicate and keep track of how many characters have been printed so that they terminate after a total of 10 characters combined.