| Safe Haskell | None |
|---|---|
| Language | Haskell2010 |
Control.Monad.Bread
Description
Sometimes you need to care about the path you take.
Suppose you're parsing some data -- you're likely using the Either
type to keep track of errors. This is good!
Unfortunately, sometimes you have weird nested data, and then when you go to parse, you get this back:
Left (IntParseError "c")
Now, you're left wondering: "Where is that c? How did it get there?
How can I minimally reproduce this?" And unfortunately, all of the
context is lost: the error has been thrown from deep in the stack, and
you're stuck munging around in the source data.
When you're dealing with some deeply nested data that might fail, you're left wondering: How do I get there from here? Let's leave breadcrumbs along the way, so that we can find our way back!
Suppose you're trying to find a specific value in a deeply nested data
structure. You can use Bread to lay breadcrumbs and then exit as
soon as you've found what you need, collecting the breadcrumbs along the
way.
- newtype BreadT crumb exit m a = BreadT {}
- runBreadT :: BreadT crumb exit m a -> m (Either ([crumb], exit) a)
- type Bread crumb exit = BreadT crumb exit Identity
- runBread :: Bread crumb exit a -> Either ([crumb], exit) a
- withCrumb :: Monad m => crumb -> BreadT crumb exit m a -> BreadT crumb exit m a
- exit :: Monad m => exit -> BreadT crumb exit m a
- handleExit :: Monad m => BreadT crumb exit m a -> (exit -> BreadT crumb exit m a) -> BreadT crumb exit m a
- crumbs :: Monad m => BreadT crumb exit m [crumb]
Documentation
newtype BreadT crumb exit m a Source #
BreadT is a monad transformer that allows you to leave breadcrumbs
of types crumb while you're performing some effects on the underlying
monad m. If you want to exit early, then will end up
returning a exit early, where Left (crumbs, early)crumbs is a list of all
breadcrumbs that you've left so far.
Since: 0.1.0.0
Instances
| MonadWriter w m => MonadWriter w (BreadT crumb exit m) Source # | |
| MonadState s m => MonadState s (BreadT crumb exit m) Source # | |
| MonadReader r m => MonadReader r (BreadT crumb exit m) Source # | The |
| Monad m => MonadError exit (BreadT crumb exit m) Source # | The |
| MonadTrans (BreadT crumb exit) Source # | |
| Monad m => Monad (BreadT crumb exit m) Source # | |
| Functor m => Functor (BreadT crumb exit m) Source # | |
| Monad m => Applicative (BreadT crumb exit m) Source # | |
| MonadIO m => MonadIO (BreadT crumb exit m) Source # | |
type Bread crumb exit = BreadT crumb exit Identity Source #
A monad that can collect breadcrumbs and exit early with them, but do nothing else.
Since: 0.1.0.0
runBread :: Bread crumb exit a -> Either ([crumb], exit) a Source #
Run a Bread computation, returning either a pair of the breadcrumbs
and error or a successful result.
Since: 0.1.0.0
withCrumb :: Monad m => crumb -> BreadT crumb exit m a -> BreadT crumb exit m a Source #
Lay a breadcrumb, so you'll know where you came from.
>>>runBread (withCrumb 'a' (exit "Nope"))Left ("a", "Nope")
Since: 0.1.0.0
exit :: Monad m => exit -> BreadT crumb exit m a Source #
Short circuit the BreadT computation. This causes the computation to
exit with the provided exit value and the crumbs collected along the
way.
Since: 0.1.0.0
handleExit :: Monad m => BreadT crumb exit m a -> (exit -> BreadT crumb exit m a) -> BreadT crumb exit m a Source #
Sometimes, a BreadT computation short-circuits with an exit, but
you don't want it to exit just yet -- perhaps you want to take
a different path. This function lets you handle exit and potentially
choose a different path.
withCrumb1 $ do exit "I'm tired"handleExitreason -> pure "No, let's persevere!"
Since: 0.1.0.0