The Monad Challenges

PureScript Edition

A set of challenges for jump starting your understanding of monads.

Outline

Set 1: Random Numbers

Set 2: Failing Computations

Set 3: Combinations

Set 4: Common Abstraction

Set 5: Do Notation

MCPrelude documentation

This project is maintained by shaunplee and is a fork of the Monad Challenges maintained by mightybyte

Creative Commons License
This work is licensed under a Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International License.

More Generators

Now write a few more functions to generate different subsets of random numbers. But first, we need to generalize a bit. If we look at the type signatures for rand and randLetter, what are the commonalities?

rand :: Seed -> Tuple Seed Int
randLetter :: Seed -> Tuple Seed Char

This common pattern can be captured in a type synonym. The key point here is that they use two different types, so you will have to introduce a type parameter. Create a type synonym that would allow us to change the type signatures of these two functions to the following:

rand :: Gen Int
randLetter :: Gen Char

This is a relatively obvious type synonym and it is pretty easy to write, but it enables a big mental leap. Now that we have this type synonym we’ve jumped up a level of abstraction and higher level patterns will become more apparent. First go back and rewrite all your existing type signatures using this Gen type synonym. Now write three new functions:

randEven :: Gen Int -- the output of rand * 2
randOdd :: Gen Int -- the output of rand * 2 + 1
randTen :: Gen Int -- the output of rand * 10

Where randEven and randOdd only generate even and odd numbers respectively, randTen only generates multiples of 10. Write randEven in terms of rand, write randOdd in terms of randEven, and write randTen however you want. There’s a general pattern lurking here. If you implement all these functions the naive way like you did fiveRands, you’ll be repeating the same pattern over and over. Figure out how to exploit the common pattern and write a function called generalA that implements this pattern. All three of the above functions will also use generalA. There are a number of different ways you could abstract this. We realize that you may not pick the right abstraction. Play around with as many different possibilities as you can think of.

SPEND SOME TIME WITH THIS BEFORE READING THE HINT!

Play with a number of abstractions and try to find the most flexible one. After you’ve spent some time with it, look at the hint here.

Pass all three of these functions a seed of 1. They’ll give you three numbers back, the product of which is 1835942764.

Previous Page - Next Page