By now you have probably realized that generating multiple random numbers this way is rather painful. You have to thread the output seed from one rand call to the input of the next call. This is tedious and error prone, so now you will create a function to make this a little easier.
repRandom :: [Gen a] -> Gen [a]
This function lets you give it a list of generators and it automatically handles the state threading for you.
The nice thing about this function is that [Gen a] is really general, so it composes well with other built-in list functions. For example:
repRandom (replicate 3 randLetter) (mkSeed 1)
This function should generate the same three letters that you got from randString3 in challenge #2.