Hey, nice! You might want to add a Readme that clarifies the order in which to read the files. I thought Layer 4 was the last file to read, not the first one.
I would love to know how you jam
Except-ion handling into this mix too
ReaderT env monad output is isomorphic to
env -> monad output, which is read as “if you give me an environment value, I will give you (but not yet run) a monadic computation that produces an
output value.” You then run that computation via
If you want to change that sentence to, “If you give me an environment value, I will give you a monadic computation that produces either a successful output (i.e.
Right output) or an error (i.e.
Left error),” then you would want a type signature like
env -> monad (Either error output).
When we translate complex monads to monad transformers, we start with the inside part first.
monad (Either error output) is synonymous with
ExceptT error monad output. If we update our function type signature to use this new “monadic type,” we get
env -> ExceptT error monad output. We now want to replace the
env -> part with
ReaderT, so we get
ReaderT env (ExceptT error monad) output.
Now that we have
ExceptT in our stack, we can use
MonadError throughout our code base.
ExceptT transformer constrains us to use only one error type throughout the entire code base. If we want to use
Variant instead, we can use checked-exceptions, which exists for this very purpose.
I believe someone packaged up a library that defines the below type, but I can’t recall where and what the library was called:
-- isomorphic to:
-- env -> monad (Either (Variant errorRows) monad output
newtype REvT env errorRows monad output =
ReaderT env (ExceptV errorRows monad) output