RWST monad transformer #1382
louthy
announced in
Announcements
Replies: 1 comment
-
Can't wait for more articles! |
Beta Was this translation helpful? Give feedback.
0 replies
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
-
The new
RWST<R, W, S, M, A>
monad-transformer is now fully-featured and ready for real-world use.For the uninitiated, the
RWST
monad-transformer combines all of the effects of theReader
,Writer
,State
, andM
monads into a single monad. You could imagine a type like this:Which stacks three monad-transformers and the monad
M
into one type. The problem with that is too much transformer stacking leads to lots of nested lambdas. TheRWST
monad-transformer smushes the Reader/Writer/State into a single layer making it more performant.You can use
Unit
for any of the type parameters if you only need two of the three capabilities. For example, if you only need reader and state effects:Or, reader and writer effects, but not state:
etc.
There's next to no overhead for doing so.
It's also worth noting that
RWST
is a very common mega-monad for constructing domain-specific monads for applications. And so, even thought it's generics heavy, you would normally wrap it up in a type that reduces the generics overhead.Let's say we wanted to create an
App
monad-transformer. Something that carries app-config, app-state, but can also lift other monads into it.First, create some records to hold the config and the state:
Then create your
App
monad-transformer type. It is simply a record that contains aRWST
monad-transformer:Then add some extensions to convert from the
K
type to the concrete type and toRun
theApp
monad-transformer:This also drops the
Unit
output from theRWST
.Then implement the traits for
App<M>
. It should be aMonadT
because it's a monad-transformer; aReadable
because it's got anAppConfig
we can read withask
; andStateful
because it's got anAppState
that weget
,gets
,modify
, andput
:Every member is simply a wrapper that calls the underlying
RWST
monad-transformer (which does all the hard work).Then we can use our new
App
monad-transformer:This leverages the
Readable
trait to get at theAppConfig
, the leverages theStateful
trait to modify theAppState
, and finally does someIO
(the liftedM
monad), by callingwriteLine
.That's great and everything, but we want to make the underlying type disappear completely. So, if we then wrap up the
Readable.ask
andStateful.modify
inApp
specific functions:Then we can make the resulting code completely
App
-centric:So, by simply wrapping up the
RWST
monad-transformer you can gain a ton of functionality without worrying how to propagate state, log changes (if you use the Writer part of RWST), or manage configuration. Very cool.Just for completeness, this is what
writeLine
looks like:I'll cover this topic in more detail in the next article of my Higher Kinds series on my blog.
This discussion was created from the release RWST monad transformer.
Beta Was this translation helpful? Give feedback.
All reactions