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.

`>>>`

Left ("a", "Nope")`runBread (withCrumb 'a' (exit "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*