constrained-monads-0.5.0.0: src/Control/Monad/Constrained/Cont.hs
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE RebindableSyntax #-}
{-# LANGUAGE UndecidableInstances #-}
-- | This module is a duplication of the Control.Monad.Cont module, from the\
-- mtl.
module Control.Monad.Constrained.Cont
(MonadCont(..)
,ContT(..)
,cont
,mapContT
,withContT
,runCont
,mapCont
,withCont)where
import Control.Monad.Constrained
import Control.Monad.Trans.Cont hiding (callCC)
import qualified Control.Monad.Trans.Cont as Cont
import qualified Control.Monad.Trans.Except as Except
import qualified Control.Monad.Trans.Identity as Identity
import qualified Control.Monad.Trans.Maybe as Maybe
import qualified Control.Monad.Trans.Reader as Reader
import qualified Control.Monad.Trans.State.Lazy as State.Lazy
import qualified Control.Monad.Trans.State.Strict as State.Strict
import qualified Prelude
-- | A class for monads which can embed continuations.
class Monad m => MonadCont m where
{- | @callCC@ (call-with-current-continuation)
calls a function with the current continuation as its argument.
Provides an escape continuation mechanism for use with Continuation monads.
Escape continuations allow to abort the current computation and return
a value immediately.
They achieve a similar effect to 'Control.Monad.Error.throwError'
and 'Control.Monad.Error.catchError'
within an 'Control.Monad.Error.Error' monad.
Advantage of this function over calling @return@ is that it makes
the continuation explicit,
allowing more flexibility and better control
(see examples in "Control.Monad.Cont").
The standard idiom used with @callCC@ is to provide a lambda-expression
to name the continuation. Then calling the named continuation anywhere
within its scope will escape from the computation,
even if it is many layers deep within nested computations.
-}
callCC :: ((a -> m b) -> m a) -> m a
instance MonadCont (ContT r m) where
callCC = Cont.callCC
instance (MonadCont m, Prelude.Monad (Unconstrained m)) =>
MonadCont (Maybe.MaybeT m) where
callCC = Maybe.liftCallCC callCC
instance MonadCont m => MonadCont (Reader.ReaderT r m) where
callCC = Reader.liftCallCC callCC
instance (MonadCont m, Prelude.Monad (Unconstrained m)) =>
MonadCont (State.Lazy.StateT s m) where
callCC = State.Lazy.liftCallCC callCC
instance (MonadCont m, Prelude.Monad (Unconstrained m)) =>
MonadCont (State.Strict.StateT s m) where
callCC = State.Strict.liftCallCC callCC
instance MonadCont m => MonadCont (Identity.IdentityT m) where
callCC = Identity.liftCallCC callCC
instance (MonadCont m, Prelude.Monad (Unconstrained m)) =>
MonadCont (Except.ExceptT e m) where
callCC = Except.liftCallCC callCC