-- Hoogle documentation, generated by Haddock
-- See Hoogle, http://www.haskell.org/hoogle/


-- | Bidirectional state monad transformer
--   
--   A Tardis is a combination of both a forwards and a backwards state
--   transformer, providing two state values that "travel" in opposite
--   directions.
--   
--   A detailed description of what a Tardis is and how to use it can be
--   found in the documentation for Control.Monad.Tardis.
@package tardis
@version 0.4.1.0


-- | The data definition of a <a>TardisT</a> as well as its primitive
--   operations, and straightforward combinators based on the primitives.
--   
--   See Control.Monad.Tardis for the general explanation of what a Tardis
--   is and how to use it.
module Control.Monad.Trans.Tardis

-- | A TardisT is parameterized by two state streams: a
--   'backwards-traveling' state and a 'forwards-traveling' state. This
--   library consistently puts the backwards-traveling state first whenever
--   the two are seen together.
newtype TardisT bw fw m a
TardisT :: ((bw, fw) -> m (a, (bw, fw))) -> TardisT bw fw m a

-- | A TardisT is merely an effectful state transformation
[runTardisT] :: TardisT bw fw m a -> (bw, fw) -> m (a, (bw, fw))

-- | Run a Tardis, and discard the final state, observing only the
--   resultant value.
evalTardisT :: Monad m => TardisT bw fw m a -> (bw, fw) -> m a

-- | Run a Tardis, and discard the resultant value, observing only the
--   final state (of both streams). Note that the <tt>final</tt> state of
--   the backwards-traveling state is the state it reaches by traveling
--   from the <tt>bottom</tt> of your code to the <tt>top</tt>.
execTardisT :: Monad m => TardisT bw fw m a -> (bw, fw) -> m (bw, fw)

-- | Using a Tardis with no monad underneath will prove to be most common
--   use case. Practical uses of a TardisT require that the underlying
--   monad be an instance of MonadFix, but note that the IO instance of
--   MonadFix is almost certainly unsuitable for use with Tardis code.
type Tardis bw fw = TardisT bw fw Identity

-- | A Tardis is merely a pure state transformation.
runTardis :: Tardis bw fw a -> (bw, fw) -> (a, (bw, fw))

-- | Run a Tardis, and discard the final state, observing only the
--   resultant value.
evalTardis :: Tardis bw fw a -> (bw, fw) -> a

-- | Run a Tardis, and discard the resultant value, observing only the
--   final state (of both streams).
execTardis :: Tardis bw fw a -> (bw, fw) -> (bw, fw)

-- | From a stateful computation, construct a Tardis. This is the pure
--   parallel to the constructor <a>TardisT</a>, and is polymorphic in the
--   transformed monad.
tardis :: Monad m => ((bw, fw) -> (a, (bw, fw))) -> TardisT bw fw m a

-- | Retrieve the current value of the 'forwards-traveling' state, which
--   therefore came forwards from the past. You can think of
--   forwards-traveling state as traveling <tt>downwards</tt> through your
--   code.
getPast :: Monad m => TardisT bw fw m fw

-- | Retrieve the current value of the 'backwards-traveling' state, which
--   therefore came backwards from the future. You can think of
--   backwards-traveling state as traveling <tt>upwards</tt> through your
--   code.
getFuture :: Monad m => TardisT bw fw m bw

-- | Set the current value of the 'backwards-traveling' state, which will
--   therefore be sent backwards to the past. This value can be retrieved
--   by calls to "getFuture" located <tt>above</tt> the current location,
--   unless it is overwritten by an intervening "sendPast".
sendPast :: Monad m => bw -> TardisT bw fw m ()

-- | Set the current value of the 'forwards-traveling' state, which will
--   therefore be sent forwards to the future. This value can be retrieved
--   by calls to "getPast" located <tt>below</tt> the current location,
--   unless it is overwritten by an intervening "sendFuture".
sendFuture :: Monad m => fw -> TardisT bw fw m ()

-- | Modify the forwards-traveling state as it passes through from past to
--   future.
modifyForwards :: MonadFix m => (fw -> fw) -> TardisT bw fw m ()

-- | Modify the backwards-traveling state as it passes through from future
--   to past.
modifyBackwards :: MonadFix m => (bw -> bw) -> TardisT bw fw m ()

-- | Retrieve a specific view of the forwards-traveling state.
getsPast :: MonadFix m => (fw -> a) -> TardisT bw fw m a

-- | Retrieve a specific view of the backwards-traveling state.
getsFuture :: MonadFix m => (bw -> a) -> TardisT bw fw m a

-- | A function that operates on the internal representation of a Tardis
--   can also be used on a Tardis.
mapTardisT :: (m (a, (bw, fw)) -> n (b, (bw, fw))) -> TardisT bw fw m a -> TardisT bw fw n b

-- | Some Tardises never observe the <tt>initial</tt> state of either state
--   stream, so it is convenient to simply hand dummy values to such
--   Tardises.
--   
--   <pre>
--   noState = (undefined, undefined)
--   </pre>
noState :: (a, b)
instance Control.Monad.Fix.MonadFix m => GHC.Base.Monad (Control.Monad.Trans.Tardis.TardisT bw fw m)
instance Control.Monad.Fix.MonadFix m => GHC.Base.Functor (Control.Monad.Trans.Tardis.TardisT bw fw m)
instance Control.Monad.Fix.MonadFix m => GHC.Base.Applicative (Control.Monad.Trans.Tardis.TardisT bw fw m)
instance Control.Monad.Trans.Class.MonadTrans (Control.Monad.Trans.Tardis.TardisT bw fw)
instance Control.Monad.Fix.MonadFix m => Control.Monad.Fix.MonadFix (Control.Monad.Trans.Tardis.TardisT bw fw m)
instance Control.Monad.Morph.MFunctor (Control.Monad.Trans.Tardis.TardisT bw fw)


-- | The class definition of a Tardis, as well as a few straightforward
--   combinators based on its primitives.
--   
--   See Control.Monad.Tardis for the general explanation of what a Tardis
--   is and how to use it.
module Control.Monad.Tardis.Class

-- | A Tardis is parameterized by two state streams: a
--   'backwards-traveling' state and a 'forwards-traveling' state. This
--   library consistently puts the backwards-traveling state first whenever
--   the two are seen together.
--   
--   Minimal complete definition: ("tardis") or ("getPast", "getFuture",
--   "sendPast", and "sendFuture").
class (Applicative m, MonadFix m) => MonadTardis bw fw m | m -> bw, m -> fw

-- | Retrieve the current value of the 'forwards-traveling' state, which
--   therefore came forwards from the past. You can think of
--   forwards-traveling state as traveling <tt>downwards</tt> through your
--   code.
getPast :: MonadTardis bw fw m => m fw

-- | Retrieve the current value of the 'backwards-traveling' state, which
--   therefore came backwards from the future. You can think of
--   backwards-traveling state as traveling <tt>upwards</tt> through your
--   code.
getFuture :: MonadTardis bw fw m => m bw

-- | Set the current value of the 'backwards-traveling' state, which will
--   therefore be sent backwards to the past. This value can be retrieved
--   by calls to "getFuture" located <tt>above</tt> the current location,
--   unless it is overwritten by an intervening "sendPast".
sendPast :: MonadTardis bw fw m => bw -> m ()

-- | Set the current value of the 'forwards-traveling' state, which will
--   therefore be sent forwards to the future. This value can be retrieved
--   by calls to "getPast" located <tt>below</tt> the current location,
--   unless it is overwritten by an intervening "sendFuture".
sendFuture :: MonadTardis bw fw m => fw -> m ()

-- | A Tardis is merely a pure state transformation.
tardis :: MonadTardis bw fw m => ((bw, fw) -> (a, (bw, fw))) -> m a

-- | Modify the forwards-traveling state as it passes through from past to
--   future.
modifyForwards :: MonadTardis bw fw m => (fw -> fw) -> m ()

-- | Modify the backwards-traveling state as it passes through from future
--   to past.
modifyBackwards :: MonadTardis bw fw m => (bw -> bw) -> m ()

-- | Retrieve a specific view of the forwards-traveling state.
getsPast :: MonadTardis bw fw m => (fw -> a) -> m a

-- | Retrieve a specific view of the backwards-traveling state.
getsFuture :: MonadTardis bw fw m => (bw -> a) -> m a
instance Control.Monad.Fix.MonadFix m => Control.Monad.Tardis.Class.MonadTardis bw fw (Control.Monad.Trans.Tardis.TardisT bw fw m)


-- | This module re-exports both <a>MonadTardis</a> and <a>TardisT</a>
--   (Wherever there is overlap, the <a>MonadTardis</a> version is
--   preferred.)
--   
--   The recommended usage of a Tardis is to import this module.
module Control.Monad.Tardis

-- | Using a Tardis with no monad underneath will prove to be most common
--   use case. Practical uses of a TardisT require that the underlying
--   monad be an instance of MonadFix, but note that the IO instance of
--   MonadFix is almost certainly unsuitable for use with Tardis code.
type Tardis bw fw = TardisT bw fw Identity

-- | A TardisT is parameterized by two state streams: a
--   'backwards-traveling' state and a 'forwards-traveling' state. This
--   library consistently puts the backwards-traveling state first whenever
--   the two are seen together.
data TardisT bw fw m a

-- | A Tardis is merely a pure state transformation.
runTardis :: Tardis bw fw a -> (bw, fw) -> (a, (bw, fw))

-- | Run a Tardis, and discard the final state, observing only the
--   resultant value.
evalTardisT :: Monad m => TardisT bw fw m a -> (bw, fw) -> m a

-- | Run a Tardis, and discard the resultant value, observing only the
--   final state (of both streams). Note that the <tt>final</tt> state of
--   the backwards-traveling state is the state it reaches by traveling
--   from the <tt>bottom</tt> of your code to the <tt>top</tt>.
execTardisT :: Monad m => TardisT bw fw m a -> (bw, fw) -> m (bw, fw)

-- | Run a Tardis, and discard the final state, observing only the
--   resultant value.
evalTardis :: Tardis bw fw a -> (bw, fw) -> a

-- | Run a Tardis, and discard the resultant value, observing only the
--   final state (of both streams).
execTardis :: Tardis bw fw a -> (bw, fw) -> (bw, fw)

-- | Some Tardises never observe the <tt>initial</tt> state of either state
--   stream, so it is convenient to simply hand dummy values to such
--   Tardises.
--   
--   <pre>
--   noState = (undefined, undefined)
--   </pre>
noState :: (a, b)
