Other Monad Transformers
Usable Now
RWS
RWS a convenience monad that combines ReaderT
, WriterT
, and StateT
into the same monad type
MaybeT
MaybeT, a computation the returns a Maybe a
. The below code snippet shows why you'd use it and when:
Before (ugly verbose code):
getName :: Effect (Maybe String)
getAge :: Effect (Maybe Int)
main :: Effect Unit
main = do
maybeName <- getName
case maybeName of
Nothing -> log "Didn't work"
Just name -> do
maybeAge <- getAge
case maybeAge of
Nothing -> log "Didn't work"
Just age -> do
log $ "Got name: " <> name <> " and age " <> show age
After (clear readable code):
getName :: Effect (Maybe String)
getAge :: Effect (Maybe Int)
main :: Effect Unit
main = do
result <- runMaybeT do
name <- MaybeT getName
age <- MaybeT getAge
pure { name, age }
case result of
Nothing -> log "Didn't work"
Just rec -> do
log $ "Got name: " <> rec.name <> " and age " <> show rec.age
You can refer to Monday Morning Haskell's post on MaybeT for more context. Replace IO
with Effect
and you'll get the idea.
ListT
ListT, a monad that returns a List a
. In addition, it provides the regular list functions you'd expect
It follows the same idea as MaybeT
above.
MonadGen
MonadGen (not included in the purescript-transformers
library): generates random data. (This is used in the Testing library later. We'll cover it when we get there.)
MonadRec
MonadRec (not included in the purescript-transformers
library): guarantees stack safety for monad transformers. For a tutorial on this type class, see Design Patterns/Stack Safety.md
.
Sketches of Monadic Control Flow
I'd like to clean this up and provide more, but I don't know what it's copyright is. Thus, I'm only linking to it here. The below link is a visual idea as to what occurs when one uses some of these monad transformers: Monads, a Field Guide
Requires More Understanding
We previously mentioned that all lawful type classes that find their roots in Category Theory have duals. The following are monad transformers for the duals of some of the monad transformers we covered here.
To quickly summarize how they work, map
ping a monadic function would change its output type whereas map
ping a comonadic function would change its input type. If the definition of Functor
's map
for a monadic function is compose
/<<<
, the definition for a comonadic function is composeFlipped
/>>>
. See the CoMonads by Example repository for a better overview of these type classes and their implementations.
- CoMonadTrans, the Transformer type class for Comonads.
- CoMonadTraced
- CoMonadStore
- CoMonadAsk
- CoMonadEnv