flatten nested comparison
data driven io
printScore is unused
don't use RWS monad

This one is a matter of taste, but I'm actually not so fond of monads. I think
they have their place, but over-use can make code more tricky to keep track of.
A monad necissarily hides things from you, it does things in the background.
This is great when the burden of managing some kind of book-keeping is onerous,
but if we can be explicit and not get too unwieldy, I prefer that.

The Reader monad is just sugar for glueing closures together, so I lifted it out
into one giant closure that binds the player's names for each part of your state
machine.

Each node in your state machine `get`s the state at the begining and `put`s it
at the end. This is the same thing as accepting the state as an argument and
passing it in the transition.

You were not actually using the writer at all, so I gutted it out.

Some simplifications of your random generation slipped into this commit too. I
managed to use lens :P.
winning boilerplate lifted
separate pure values into the where clause