This package allows you to invoke a function on one monadic
type passing it an argument of a different monadic type. The
canonical example is using a function such as `finally`

or
`bracket`

to ensure cleanup is run regardless of any
exceptions thrown by a computation such as `x :: ``ReaderT`

MyConfig `IO`

b

. If `x`

uses the `ReaderT`

function `ask`

,
it cannot be re-written to run in the `IO`

monad, and hence
cannot be executed with a construction like `lift`

(x
``finally`

` cleanup)

. Instead, you must use the `wrap`

method, provided by module `Control.Monad.Wrap`

in this
package.

This package contains several other modules:
`Control.Monad.WrapIO`

wraps an IO action through multiple
monad transformers. `Control.Monad.WrapBase`

generalizes the
concept to other base monads besides IO.
`Control.Monad.MultiWrap`

implements `mwrap`

, a method that
behaves like `wrap`

but allows wrapping through multiple
nested layers of monad transformer. The module
`Control.Monad.MultiLift`

provides `mlift`

, a version of
`lift`

that similarly lifts through multiple nested monad
transformers.

Since this library was first released, an alternate approach
was introduced by the `monad-control`

package.
`monad-control`

is now the standard. However, this package,
`monad-wrap`

, stands as an example of accomplishing similar
goals with fewer language extensions and less complexity. In
particular, `monad-wrap`

does not use `RankNTypes`

or
`TypeFamilies`

, both required by `monad-control`

. Moreover,
`monad-wrap`

is much smaller--no `MonadWrap`

method requires
more than one line of code. Both `monad-wrap`

and
`monad-control`

require `UndecidableInstances`

, but
`Control.Monad.Wrap`

itself does not require that extension,
only the other modules.