4 ms·
There are two independent parts. The Z monad is nothing more than a ReaderT monad giving access to some config and environment information. Since it's a transfo
by tel 13y ago
There are two independent parts. The Z monad is nothing more than a ReaderT monad giving access to some config and environment information. Since it's a transformer they can execute actions in higher monads (like IO) pretty easily from Z, but it can also be used in pure code if you just need the configuration information.
Parallel to that is the ZResultT monad. It's built on the ZResult monad (it should be easy enough to write a Monad instance for it anyway) which looks like an Identity monad with some "Z-specific" error handling layered in. ZResultT just lets you have a transformer stack interleaved with the ZResults.
Then you combine those two stacks in ZZ which gives you both "Z-related" configuration and "Z-related" error states.
It looks like the whole thing is specialized to make it easy to build functions pure functions which only need a handful of the effects and then weave them together into the ZZ monad which is likely to be run at the top level, right below Yesod.