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 (m1 :: Type -> Type) a.
  Monad m1 =>
  t m1 a -> m1 (Tunnel t a))
 -> m (Tunnel t a))
-> t m a
forall (m :: Type -> Type) r.
Monad m =>
((forall (m1 :: Type -> Type) a.
  Monad m1 =>
  t m1 a -> m1 (Tunnel t a))
 -> m (Tunnel t r))
-> t m r
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 (m1 :: Type -> Type) a.
   Monad m1 =>
   t m1 a -> m1 (Tunnel t a))
  -> m (Tunnel t a))
 -> t m a)
-> ((forall (m1 :: Type -> Type) a.
     Monad m1 =>
     t m1 a -> m1 (Tunnel t a))
    -> m (Tunnel t a))
-> t m a
forall a b. (a -> b) -> a -> b
$ \forall (m1 :: Type -> Type) a.
Monad m1 =>
t m1 a -> m1 (Tunnel t a)
unlift ->
            ((Tunnel t a -> m b) -> m (Tunnel t a)) -> m (Tunnel t a)
forall a b. ((a -> m b) -> m a) -> m a
forall (m :: Type -> Type) a b.
MonadCont m =>
((a -> m b) -> m a) -> m a
callCC (((Tunnel t a -> m b) -> m (Tunnel t a)) -> m (Tunnel t a))
-> ((Tunnel t a -> m b) -> m (Tunnel t a)) -> m (Tunnel t a)
forall a b. (a -> b) -> a -> b
$ \Tunnel t a -> m b
cont ->
                t m a -> m (Tunnel t a)
forall (m1 :: Type -> Type) a.
Monad m1 =>
t m1 a -> m1 (Tunnel t a)
unlift (t m a -> m (Tunnel t a)) -> t m a -> m (Tunnel t a)
forall a b. (a -> b) -> a -> b
$ (a -> t m b) -> t m a
call ((a -> t m b) -> t m a) -> (a -> t m b) -> t m a
forall a b. (a -> b) -> a -> b
$ \a
a -> m b -> t m b
forall (m :: Type -> Type) a. Monad m => m a -> t m a
forall (t :: TransKind) (m :: Type -> Type) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift (m b -> t m b) -> m b -> t m b
forall a b. (a -> b) -> a -> b
$ Tunnel t a -> m b
cont (Tunnel t a -> m b) -> Tunnel t a -> m b
forall a b. (a -> b) -> a -> b
$ Identity (Tunnel t a) -> Tunnel t a
forall a. Identity a -> a
runIdentity (Identity (Tunnel t a) -> Tunnel t a)
-> Identity (Tunnel t a) -> Tunnel t a
forall a b. (a -> b) -> a -> b
$ t Identity a -> Identity (Tunnel t a)
forall (m1 :: Type -> Type) a.
Monad m1 =>
t m1 a -> m1 (Tunnel t a)
unlift (t Identity a -> Identity (Tunnel t a))
-> t Identity a -> Identity (Tunnel t a)
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 ((Monad (t Identity) => t Identity a) -> t Identity a)
-> (Monad (t Identity) => t Identity a) -> t Identity a
forall a b. (a -> b) -> a -> b
$ a -> t Identity a
forall a. a -> t Identity a
forall (m :: Type -> Type) a. Monad m => a -> m a
return a
a