Supply a monad over the cache state.

This gives us an easy way to track the cache state over a set of writing operations.
Use the State monad to thread the code and avoid referencing "gen" all the time.

This also paves the way for a proper handling of cache tracking in the code base.