{-# LANGUAGE RebindableSyntax #-} -- | 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 qualified Control.Monad.Trans.Cont as Cont import Control.Monad.Trans.Cont hiding (callCC) 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 Control.Monad.Trans.Identity as Identity import qualified Control.Monad.Trans.Maybe as Maybe import qualified Control.Monad.Trans.Except as Except -- | 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 => 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 => MonadCont (State.Lazy.StateT s m) where callCC = State.Lazy.liftCallCC callCC instance MonadCont 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 => MonadCont (Except.ExceptT e m) where callCC = Except.liftCallCC callCC