module Control.Monad.Ology.General.Cont where

import Control.Monad.Ology.General.Trans.Constraint
import Control.Monad.Ology.General.Trans.Trans
import Control.Monad.Ology.General.Trans.Tunnel
import Import

class Monad m => MonadCont m where
    callCC :: ((a -> m b) -> m a) -> m a

instance (MonadTransTunnel t, MonadCont m, Monad (t m)) => MonadCont (t m) where
    callCC :: forall a b. ((a -> t m b) -> t m a) -> t m a
callCC (a -> t m b) -> t m a
call =
        forall (t :: TransKind) (m :: Type -> Type) r.
(MonadTransTunnel t, Monad m) =>
((forall (m1 :: Type -> Type) a.
  Monad m1 =>
  t m1 a -> m1 (Tunnel t a))
 -> m (Tunnel t r))
-> t m r
tunnel forall a b. (a -> b) -> a -> b
$ \forall (m1 :: Type -> Type) a.
Monad m1 =>
t m1 a -> m1 (Tunnel t a)
unlift ->
            forall (m :: Type -> Type) a b.
MonadCont m =>
((a -> m b) -> m a) -> m a
callCC forall a b. (a -> b) -> a -> b
$ \Tunnel t a -> m b
cont ->
                forall (m1 :: Type -> Type) a.
Monad m1 =>
t m1 a -> m1 (Tunnel t a)
unlift forall a b. (a -> b) -> a -> b
$ (a -> t m b) -> t m a
call forall a b. (a -> b) -> a -> b
$ \a
a -> forall (t :: TransKind) (m :: Type -> Type) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift forall a b. (a -> b) -> a -> b
$ Tunnel t a -> m b
cont forall a b. (a -> b) -> a -> b
$ forall a. Identity a -> a
runIdentity forall a b. (a -> b) -> a -> b
$ forall (m1 :: Type -> Type) a.
Monad m1 =>
t m1 a -> m1 (Tunnel t a)
unlift forall a b. (a -> b) -> a -> b
$ forall (c :: (Type -> Type) -> Constraint) (t :: TransKind)
       (m :: Type -> Type) a.
(TransConstraint c t, c m) =>
(c (t m) => t m a) -> t m a
withTransConstraintTM @Monad forall a b. (a -> b) -> a -> b
$ forall (m :: Type -> Type) a. Monad m => a -> m a
return a
a