Safe Haskell | None |
---|---|
Language | Haskell2010 |
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
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 crumb
s 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.
withCrumb
1 $ do exit "I'm tired"handleExit
reason -> pure "No, let's persevere!"
Since: 0.1.0.0