MonadStack-0.1.0.3: Generalizing lift to monad stacks

Copyright(C) 2015 by Brian Hurt
LicenseBSD 2-Clause
MaintainerBrian Hurt <bhurt42@gmail.com>
Stabilityexperimental
Portabilitysafe
Safe HaskellSafe-Inferred
LanguageHaskell2010

Control.Monad.MonadStack

Description

MonadStack provides a multi-level lift function, called liftFrom. It allows lifting from an arbitrary monad in a monad transformer stack up to any higher monad in that stack. And example use might be:

   newtype MyMonad = MyMonad ... deriving (Monad)

   doFoo :: MonadStack MyMonad m => something -> m whatever
   doFoo arg = liftFrom go
       where
           go :: MyMonad whatever
           go = do ...

This allows calling doFoo either in the MyMonad monad, or in any monad transformer stack on top of the MyMonad.

MonadStack is similar to the Control.Monad.Base module from the transformers-base package, except that there is no functional dependency between the monads. A monad transformer stack can only have one base, but it can have several MonadStack implementations.

MonadStack is very similar to the Control.Monad.Lifter module from the MonadCompose package, with two exceptions. One, MonadStack does not require the OverlappingInstances and UndecidableInstances extensions- both of which are prone to generating hard to diagnose bugs. But this implies two, that MonadStack is much less feature-rich than Lifter is. Specifically, MonadStack only works with "proper" monad transformers (those that implment MonadTrans), while Lifter generalizes the notion of lifting and works with more different types of monads, especially MonadPlus.

Synopsis

Documentation

class MonadStack m n where Source

A multi-level lifter class.

The existance of an implementation of MonadStack m n implies that is is possible to convert an m a into an n a via zero or more applications of lift.

Methods

liftFrom :: m a -> n a Source

Instances

MonadStack m m

The base case implementation

You can always convert an m a into an m a by applying 0 lifts. This is like treating an m a as a zero-level monad transformer stack (a monad transformer stack with no monad transformers), and liftFrom is just the id function.

(Monad k, Monad m, MonadTrans n, MonadStack k m) => MonadStack k (n m)

The inductive step implementation

If there exists an implementation of MonadStack k m for monads k and m (that is, we can perform a liftFrom to convert a k a to a m a), and n is a monad transformer, then we can construct an implementation of MonadStack k (n m), by just adding one more lift to the liftFrom.