{-# LANGUAGE CPP #-}
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE GeneralizedNewtypeDeriving #-}
{-# LANGUAGE MultiParamTypeClasses #-}
{-# LANGUAGE TypeFamilies #-}
{-# LANGUAGE UndecidableInstances #-}
module Lambdabot.Module
    ( Module(..)
    , newModule
    
    , ModuleID
    , newModuleID
    
    , ModuleInfo(..)
    , ModuleT
    , runModuleT
    ) where

import qualified Lambdabot.Command as Cmd
import Lambdabot.Config
import Lambdabot.Logging
import {-# SOURCE #-} Lambdabot.Monad
import Lambdabot.Util.Serial

import Control.Applicative
import Control.Concurrent (MVar)
import Control.Monad
import Control.Monad.Fail (MonadFail)
import qualified Control.Monad.Fail
import Control.Monad.Base
import Control.Monad.Reader (MonadReader(..), ReaderT(..), asks)
import Control.Monad.Trans (MonadTrans(..), MonadIO(..))
import Control.Monad.Trans.Control
import Data.Unique.Tag
import Control.Monad.Catch (MonadThrow, MonadCatch, MonadMask)
#if !defined(MIN_VERSION_haskeline) || !MIN_VERSION_haskeline(0,8,0)
import System.Console.Haskeline.MonadException (MonadException)
#endif

------------------------------------------------------------------------

-- | The Module type class.
data Module st = Module {
        -- | If the module wants its state to be saved, this function should
        --   return a Serial.
        --
        --   The default implementation returns Nothing.
        Module st -> Maybe (Serial st)
moduleSerialize :: !(Maybe (Serial st)),

        -- | If the module maintains state, this method specifies the default state
        --   (for example in case the state can't be read from a state).
        --
        --   The default implementation returns an error and assumes the state is
        --   never accessed.
        Module st -> LB st
moduleDefState  :: !(LB st),

        -- | Is the module sticky? Sticky modules (as well as static ones) can't be
        --   unloaded. By default, modules are not sticky.
        Module st -> Bool
moduleSticky    :: !Bool,

        -- | The commands the module listens to.
        Module st -> ModuleT st LB [Command (ModuleT st LB)]
moduleCmds      :: !(ModuleT st LB [Cmd.Command (ModuleT st LB)]),

        -- | Initialize the module. The default implementation does nothing.
        Module st -> ModuleT st LB ()
moduleInit      :: !(ModuleT st LB ()),

        -- | Finalize the module. The default implementation does nothing.
        Module st -> ModuleT st LB ()
moduleExit      :: !(ModuleT st LB ()),

        -- | Process contextual input. A plugin that implements 'contextual'
        -- is able to respond to text not part of a normal command.
        Module st -> String -> Cmd (ModuleT st LB) ()
contextual
            :: !(String                           --  the text
             -> Cmd.Cmd (ModuleT st LB) ())       -- ^ the action
    }

------------------------------------------------------------------------

newModule :: Module st
newModule :: Module st
newModule = Module :: forall st.
Maybe (Serial st)
-> LB st
-> Bool
-> ModuleT st LB [Command (ModuleT st LB)]
-> ModuleT st LB ()
-> ModuleT st LB ()
-> (String -> Cmd (ModuleT st LB) ())
-> Module st
Module
    { contextual :: String -> Cmd (ModuleT st LB) ()
contextual         = \String
_ -> () -> Cmd (ModuleT st LB) ()
forall (m :: * -> *) a. Monad m => a -> m a
return ()
    , moduleCmds :: ModuleT st LB [Command (ModuleT st LB)]
moduleCmds         = [Command (ModuleT st LB)]
-> ModuleT st LB [Command (ModuleT st LB)]
forall (m :: * -> *) a. Monad m => a -> m a
return []
    , moduleExit :: ModuleT st LB ()
moduleExit         = () -> ModuleT st LB ()
forall (m :: * -> *) a. Monad m => a -> m a
return ()
    , moduleInit :: ModuleT st LB ()
moduleInit         = () -> ModuleT st LB ()
forall (m :: * -> *) a. Monad m => a -> m a
return ()
    , moduleSticky :: Bool
moduleSticky       = Bool
False
    , moduleSerialize :: Maybe (Serial st)
moduleSerialize    = Maybe (Serial st)
forall a. Maybe a
Nothing
    , moduleDefState :: LB st
moduleDefState     = st -> LB st
forall (m :: * -> *) a. Monad m => a -> m a
return (st -> LB st) -> st -> LB st
forall a b. (a -> b) -> a -> b
$ String -> st
forall a. HasCallStack => String -> a
error String
"state not initialized"
    }

newtype ModuleID st = ModuleID (Tag RealWorld st)
    deriving (ModuleID a -> ModuleID b -> Maybe (a :~: b)
(forall a b. ModuleID a -> ModuleID b -> Maybe (a :~: b))
-> GEq ModuleID
forall a b. ModuleID a -> ModuleID b -> Maybe (a :~: b)
forall k (f :: k -> *).
(forall (a :: k) (b :: k). f a -> f b -> Maybe (a :~: b)) -> GEq f
geq :: ModuleID a -> ModuleID b -> Maybe (a :~: b)
$cgeq :: forall a b. ModuleID a -> ModuleID b -> Maybe (a :~: b)
GEq, GEq ModuleID
GEq ModuleID
-> (forall a b. ModuleID a -> ModuleID b -> GOrdering a b)
-> GCompare ModuleID
ModuleID a -> ModuleID b -> GOrdering a b
forall a b. ModuleID a -> ModuleID b -> GOrdering a b
forall k (f :: k -> *).
GEq f
-> (forall (a :: k) (b :: k). f a -> f b -> GOrdering a b)
-> GCompare f
gcompare :: ModuleID a -> ModuleID b -> GOrdering a b
$cgcompare :: forall a b. ModuleID a -> ModuleID b -> GOrdering a b
$cp1GCompare :: GEq ModuleID
GCompare)

newModuleID :: IO (ModuleID st)
newModuleID :: IO (ModuleID st)
newModuleID = Tag RealWorld st -> ModuleID st
forall st. Tag RealWorld st -> ModuleID st
ModuleID (Tag RealWorld st -> ModuleID st)
-> IO (Tag RealWorld st) -> IO (ModuleID st)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> IO (Tag RealWorld st)
forall (m :: * -> *) a. PrimMonad m => m (Tag (PrimState m) a)
newTag

-- |Info about a running module.
data ModuleInfo st = ModuleInfo
    { ModuleInfo st -> String
moduleName   :: !String
    , ModuleInfo st -> ModuleID st
moduleID     :: !(ModuleID st)
    , ModuleInfo st -> Module st
theModule    :: !(Module st)
    , ModuleInfo st -> MVar st
moduleState  :: !(MVar st)
    }

-- | This transformer encodes the additional information a module might
--   need to access its name or its state.
newtype ModuleT st m a = ModuleT { ModuleT st m a -> ReaderT (ModuleInfo st) m a
unModuleT :: ReaderT (ModuleInfo st) m a }
    deriving (Functor (ModuleT st m)
a -> ModuleT st m a
Functor (ModuleT st m)
-> (forall a. a -> ModuleT st m a)
-> (forall a b.
    ModuleT st m (a -> b) -> ModuleT st m a -> ModuleT st m b)
-> (forall a b c.
    (a -> b -> c)
    -> ModuleT st m a -> ModuleT st m b -> ModuleT st m c)
-> (forall a b. ModuleT st m a -> ModuleT st m b -> ModuleT st m b)
-> (forall a b. ModuleT st m a -> ModuleT st m b -> ModuleT st m a)
-> Applicative (ModuleT st m)
ModuleT st m a -> ModuleT st m b -> ModuleT st m b
ModuleT st m a -> ModuleT st m b -> ModuleT st m a
ModuleT st m (a -> b) -> ModuleT st m a -> ModuleT st m b
(a -> b -> c) -> ModuleT st m a -> ModuleT st m b -> ModuleT st m c
forall a. a -> ModuleT st m a
forall a b. ModuleT st m a -> ModuleT st m b -> ModuleT st m a
forall a b. ModuleT st m a -> ModuleT st m b -> ModuleT st m b
forall a b.
ModuleT st m (a -> b) -> ModuleT st m a -> ModuleT st m b
forall a b c.
(a -> b -> c) -> ModuleT st m a -> ModuleT st m b -> ModuleT st m c
forall st (m :: * -> *). Applicative m => Functor (ModuleT st m)
forall st (m :: * -> *) a. Applicative m => a -> ModuleT st m a
forall st (m :: * -> *) a b.
Applicative m =>
ModuleT st m a -> ModuleT st m b -> ModuleT st m a
forall st (m :: * -> *) a b.
Applicative m =>
ModuleT st m a -> ModuleT st m b -> ModuleT st m b
forall st (m :: * -> *) a b.
Applicative m =>
ModuleT st m (a -> b) -> ModuleT st m a -> ModuleT st m b
forall st (m :: * -> *) a b c.
Applicative m =>
(a -> b -> c) -> ModuleT st m a -> ModuleT st m b -> ModuleT st m c
forall (f :: * -> *).
Functor f
-> (forall a. a -> f a)
-> (forall a b. f (a -> b) -> f a -> f b)
-> (forall a b c. (a -> b -> c) -> f a -> f b -> f c)
-> (forall a b. f a -> f b -> f b)
-> (forall a b. f a -> f b -> f a)
-> Applicative f
<* :: ModuleT st m a -> ModuleT st m b -> ModuleT st m a
$c<* :: forall st (m :: * -> *) a b.
Applicative m =>
ModuleT st m a -> ModuleT st m b -> ModuleT st m a
*> :: ModuleT st m a -> ModuleT st m b -> ModuleT st m b
$c*> :: forall st (m :: * -> *) a b.
Applicative m =>
ModuleT st m a -> ModuleT st m b -> ModuleT st m b
liftA2 :: (a -> b -> c) -> ModuleT st m a -> ModuleT st m b -> ModuleT st m c
$cliftA2 :: forall st (m :: * -> *) a b c.
Applicative m =>
(a -> b -> c) -> ModuleT st m a -> ModuleT st m b -> ModuleT st m c
<*> :: ModuleT st m (a -> b) -> ModuleT st m a -> ModuleT st m b
$c<*> :: forall st (m :: * -> *) a b.
Applicative m =>
ModuleT st m (a -> b) -> ModuleT st m a -> ModuleT st m b
pure :: a -> ModuleT st m a
$cpure :: forall st (m :: * -> *) a. Applicative m => a -> ModuleT st m a
$cp1Applicative :: forall st (m :: * -> *). Applicative m => Functor (ModuleT st m)
Applicative, a -> ModuleT st m b -> ModuleT st m a
(a -> b) -> ModuleT st m a -> ModuleT st m b
(forall a b. (a -> b) -> ModuleT st m a -> ModuleT st m b)
-> (forall a b. a -> ModuleT st m b -> ModuleT st m a)
-> Functor (ModuleT st m)
forall a b. a -> ModuleT st m b -> ModuleT st m a
forall a b. (a -> b) -> ModuleT st m a -> ModuleT st m b
forall st (m :: * -> *) a b.
Functor m =>
a -> ModuleT st m b -> ModuleT st m a
forall st (m :: * -> *) a b.
Functor m =>
(a -> b) -> ModuleT st m a -> ModuleT st m b
forall (f :: * -> *).
(forall a b. (a -> b) -> f a -> f b)
-> (forall a b. a -> f b -> f a) -> Functor f
<$ :: a -> ModuleT st m b -> ModuleT st m a
$c<$ :: forall st (m :: * -> *) a b.
Functor m =>
a -> ModuleT st m b -> ModuleT st m a
fmap :: (a -> b) -> ModuleT st m a -> ModuleT st m b
$cfmap :: forall st (m :: * -> *) a b.
Functor m =>
(a -> b) -> ModuleT st m a -> ModuleT st m b
Functor, Applicative (ModuleT st m)
a -> ModuleT st m a
Applicative (ModuleT st m)
-> (forall a b.
    ModuleT st m a -> (a -> ModuleT st m b) -> ModuleT st m b)
-> (forall a b. ModuleT st m a -> ModuleT st m b -> ModuleT st m b)
-> (forall a. a -> ModuleT st m a)
-> Monad (ModuleT st m)
ModuleT st m a -> (a -> ModuleT st m b) -> ModuleT st m b
ModuleT st m a -> ModuleT st m b -> ModuleT st m b
forall a. a -> ModuleT st m a
forall a b. ModuleT st m a -> ModuleT st m b -> ModuleT st m b
forall a b.
ModuleT st m a -> (a -> ModuleT st m b) -> ModuleT st m b
forall st (m :: * -> *). Monad m => Applicative (ModuleT st m)
forall st (m :: * -> *) a. Monad m => a -> ModuleT st m a
forall st (m :: * -> *) a b.
Monad m =>
ModuleT st m a -> ModuleT st m b -> ModuleT st m b
forall st (m :: * -> *) a b.
Monad m =>
ModuleT st m a -> (a -> ModuleT st m b) -> ModuleT st m b
forall (m :: * -> *).
Applicative m
-> (forall a b. m a -> (a -> m b) -> m b)
-> (forall a b. m a -> m b -> m b)
-> (forall a. a -> m a)
-> Monad m
return :: a -> ModuleT st m a
$creturn :: forall st (m :: * -> *) a. Monad m => a -> ModuleT st m a
>> :: ModuleT st m a -> ModuleT st m b -> ModuleT st m b
$c>> :: forall st (m :: * -> *) a b.
Monad m =>
ModuleT st m a -> ModuleT st m b -> ModuleT st m b
>>= :: ModuleT st m a -> (a -> ModuleT st m b) -> ModuleT st m b
$c>>= :: forall st (m :: * -> *) a b.
Monad m =>
ModuleT st m a -> (a -> ModuleT st m b) -> ModuleT st m b
$cp1Monad :: forall st (m :: * -> *). Monad m => Applicative (ModuleT st m)
Monad, MonadReader (ModuleInfo st), 
        m a -> ModuleT st m a
(forall (m :: * -> *) a. Monad m => m a -> ModuleT st m a)
-> MonadTrans (ModuleT st)
forall st (m :: * -> *) a. Monad m => m a -> ModuleT st m a
forall (m :: * -> *) a. Monad m => m a -> ModuleT st m a
forall (t :: (* -> *) -> * -> *).
(forall (m :: * -> *) a. Monad m => m a -> t m a) -> MonadTrans t
lift :: m a -> ModuleT st m a
$clift :: forall st (m :: * -> *) a. Monad m => m a -> ModuleT st m a
MonadTrans, Monad (ModuleT st m)
Monad (ModuleT st m)
-> (forall a. IO a -> ModuleT st m a) -> MonadIO (ModuleT st m)
IO a -> ModuleT st m a
forall a. IO a -> ModuleT st m a
forall st (m :: * -> *). MonadIO m => Monad (ModuleT st m)
forall st (m :: * -> *) a. MonadIO m => IO a -> ModuleT st m a
forall (m :: * -> *).
Monad m -> (forall a. IO a -> m a) -> MonadIO m
liftIO :: IO a -> ModuleT st m a
$cliftIO :: forall st (m :: * -> *) a. MonadIO m => IO a -> ModuleT st m a
$cp1MonadIO :: forall st (m :: * -> *). MonadIO m => Monad (ModuleT st m)
MonadIO, Monad (ModuleT st m)
Monad (ModuleT st m)
-> (forall a. Config a -> ModuleT st m a)
-> MonadConfig (ModuleT st m)
Config a -> ModuleT st m a
forall a. Config a -> ModuleT st m a
forall st (m :: * -> *). MonadConfig m => Monad (ModuleT st m)
forall st (m :: * -> *) a.
MonadConfig m =>
Config a -> ModuleT st m a
forall (m :: * -> *).
Monad m -> (forall a. Config a -> m a) -> MonadConfig m
getConfig :: Config a -> ModuleT st m a
$cgetConfig :: forall st (m :: * -> *) a.
MonadConfig m =>
Config a -> ModuleT st m a
$cp1MonadConfig :: forall st (m :: * -> *). MonadConfig m => Monad (ModuleT st m)
MonadConfig, Monad (ModuleT st m)
Monad (ModuleT st m)
-> (forall a. String -> ModuleT st m a) -> MonadFail (ModuleT st m)
String -> ModuleT st m a
forall a. String -> ModuleT st m a
forall st (m :: * -> *). MonadFail m => Monad (ModuleT st m)
forall st (m :: * -> *) a. MonadFail m => String -> ModuleT st m a
forall (m :: * -> *).
Monad m -> (forall a. String -> m a) -> MonadFail m
fail :: String -> ModuleT st m a
$cfail :: forall st (m :: * -> *) a. MonadFail m => String -> ModuleT st m a
$cp1MonadFail :: forall st (m :: * -> *). MonadFail m => Monad (ModuleT st m)
MonadFail,
#if !defined(MIN_VERSION_haskeline) || !MIN_VERSION_haskeline(0,8,0)
        MonadException,
#endif
        Monad (ModuleT st m)
e -> ModuleT st m a
Monad (ModuleT st m)
-> (forall e a. Exception e => e -> ModuleT st m a)
-> MonadThrow (ModuleT st m)
forall e a. Exception e => e -> ModuleT st m a
forall st (m :: * -> *). MonadThrow m => Monad (ModuleT st m)
forall st (m :: * -> *) e a.
(MonadThrow m, Exception e) =>
e -> ModuleT st m a
forall (m :: * -> *).
Monad m -> (forall e a. Exception e => e -> m a) -> MonadThrow m
throwM :: e -> ModuleT st m a
$cthrowM :: forall st (m :: * -> *) e a.
(MonadThrow m, Exception e) =>
e -> ModuleT st m a
$cp1MonadThrow :: forall st (m :: * -> *). MonadThrow m => Monad (ModuleT st m)
MonadThrow, MonadThrow (ModuleT st m)
MonadThrow (ModuleT st m)
-> (forall e a.
    Exception e =>
    ModuleT st m a -> (e -> ModuleT st m a) -> ModuleT st m a)
-> MonadCatch (ModuleT st m)
ModuleT st m a -> (e -> ModuleT st m a) -> ModuleT st m a
forall e a.
Exception e =>
ModuleT st m a -> (e -> ModuleT st m a) -> ModuleT st m a
forall st (m :: * -> *). MonadCatch m => MonadThrow (ModuleT st m)
forall st (m :: * -> *) e a.
(MonadCatch m, Exception e) =>
ModuleT st m a -> (e -> ModuleT st m a) -> ModuleT st m a
forall (m :: * -> *).
MonadThrow m
-> (forall e a. Exception e => m a -> (e -> m a) -> m a)
-> MonadCatch m
catch :: ModuleT st m a -> (e -> ModuleT st m a) -> ModuleT st m a
$ccatch :: forall st (m :: * -> *) e a.
(MonadCatch m, Exception e) =>
ModuleT st m a -> (e -> ModuleT st m a) -> ModuleT st m a
$cp1MonadCatch :: forall st (m :: * -> *). MonadCatch m => MonadThrow (ModuleT st m)
MonadCatch, MonadCatch (ModuleT st m)
MonadCatch (ModuleT st m)
-> (forall b.
    ((forall a. ModuleT st m a -> ModuleT st m a) -> ModuleT st m b)
    -> ModuleT st m b)
-> (forall b.
    ((forall a. ModuleT st m a -> ModuleT st m a) -> ModuleT st m b)
    -> ModuleT st m b)
-> (forall a b c.
    ModuleT st m a
    -> (a -> ExitCase b -> ModuleT st m c)
    -> (a -> ModuleT st m b)
    -> ModuleT st m (b, c))
-> MonadMask (ModuleT st m)
ModuleT st m a
-> (a -> ExitCase b -> ModuleT st m c)
-> (a -> ModuleT st m b)
-> ModuleT st m (b, c)
((forall a. ModuleT st m a -> ModuleT st m a) -> ModuleT st m b)
-> ModuleT st m b
((forall a. ModuleT st m a -> ModuleT st m a) -> ModuleT st m b)
-> ModuleT st m b
forall b.
((forall a. ModuleT st m a -> ModuleT st m a) -> ModuleT st m b)
-> ModuleT st m b
forall a b c.
ModuleT st m a
-> (a -> ExitCase b -> ModuleT st m c)
-> (a -> ModuleT st m b)
-> ModuleT st m (b, c)
forall st (m :: * -> *). MonadMask m => MonadCatch (ModuleT st m)
forall st (m :: * -> *) b.
MonadMask m =>
((forall a. ModuleT st m a -> ModuleT st m a) -> ModuleT st m b)
-> ModuleT st m b
forall st (m :: * -> *) a b c.
MonadMask m =>
ModuleT st m a
-> (a -> ExitCase b -> ModuleT st m c)
-> (a -> ModuleT st m b)
-> ModuleT st m (b, c)
forall (m :: * -> *).
MonadCatch m
-> (forall b. ((forall a. m a -> m a) -> m b) -> m b)
-> (forall b. ((forall a. m a -> m a) -> m b) -> m b)
-> (forall a b c.
    m a -> (a -> ExitCase b -> m c) -> (a -> m b) -> m (b, c))
-> MonadMask m
generalBracket :: ModuleT st m a
-> (a -> ExitCase b -> ModuleT st m c)
-> (a -> ModuleT st m b)
-> ModuleT st m (b, c)
$cgeneralBracket :: forall st (m :: * -> *) a b c.
MonadMask m =>
ModuleT st m a
-> (a -> ExitCase b -> ModuleT st m c)
-> (a -> ModuleT st m b)
-> ModuleT st m (b, c)
uninterruptibleMask :: ((forall a. ModuleT st m a -> ModuleT st m a) -> ModuleT st m b)
-> ModuleT st m b
$cuninterruptibleMask :: forall st (m :: * -> *) b.
MonadMask m =>
((forall a. ModuleT st m a -> ModuleT st m a) -> ModuleT st m b)
-> ModuleT st m b
mask :: ((forall a. ModuleT st m a -> ModuleT st m a) -> ModuleT st m b)
-> ModuleT st m b
$cmask :: forall st (m :: * -> *) b.
MonadMask m =>
((forall a. ModuleT st m a -> ModuleT st m a) -> ModuleT st m b)
-> ModuleT st m b
$cp1MonadMask :: forall st (m :: * -> *). MonadMask m => MonadCatch (ModuleT st m)
MonadMask)

runModuleT :: ModuleT st m a -> ModuleInfo st -> m a
runModuleT :: ModuleT st m a -> ModuleInfo st -> m a
runModuleT = ReaderT (ModuleInfo st) m a -> ModuleInfo st -> m a
forall r (m :: * -> *) a. ReaderT r m a -> r -> m a
runReaderT (ReaderT (ModuleInfo st) m a -> ModuleInfo st -> m a)
-> (ModuleT st m a -> ReaderT (ModuleInfo st) m a)
-> ModuleT st m a
-> ModuleInfo st
-> m a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ModuleT st m a -> ReaderT (ModuleInfo st) m a
forall st (m :: * -> *) a.
ModuleT st m a -> ReaderT (ModuleInfo st) m a
unModuleT

instance MonadLogging m => MonadLogging (ModuleT st m) where
    getCurrentLogger :: ModuleT st m [String]
getCurrentLogger = do
        [String]
parent <- m [String] -> ModuleT st m [String]
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift m [String]
forall (m :: * -> *). MonadLogging m => m [String]
getCurrentLogger
        String
self   <- (ModuleInfo st -> String) -> ModuleT st m String
forall r (m :: * -> *) a. MonadReader r m => (r -> a) -> m a
asks ModuleInfo st -> String
forall st. ModuleInfo st -> String
moduleName
        [String] -> ModuleT st m [String]
forall (m :: * -> *) a. Monad m => a -> m a
return ([String]
parent [String] -> [String] -> [String]
forall a. [a] -> [a] -> [a]
++ [String
"Plugin", String
self])
    logM :: String -> Priority -> String -> ModuleT st m ()
logM String
a Priority
b String
c = m () -> ModuleT st m ()
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift (String -> Priority -> String -> m ()
forall (m :: * -> *).
MonadLogging m =>
String -> Priority -> String -> m ()
logM String
a Priority
b String
c)

instance MonadBase b m => MonadBase b (ModuleT st m) where
    liftBase :: b α -> ModuleT st m α
liftBase = m α -> ModuleT st m α
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift (m α -> ModuleT st m α) -> (b α -> m α) -> b α -> ModuleT st m α
forall b c a. (b -> c) -> (a -> b) -> a -> c
. b α -> m α
forall (b :: * -> *) (m :: * -> *) α. MonadBase b m => b α -> m α
liftBase

instance MonadTransControl (ModuleT st) where
    type StT (ModuleT st) a = a
    liftWith :: (Run (ModuleT st) -> m a) -> ModuleT st m a
liftWith Run (ModuleT st) -> m a
f = do
        ModuleInfo st
r <- ReaderT (ModuleInfo st) m (ModuleInfo st)
-> ModuleT st m (ModuleInfo st)
forall st (m :: * -> *) a.
ReaderT (ModuleInfo st) m a -> ModuleT st m a
ModuleT ReaderT (ModuleInfo st) m (ModuleInfo st)
forall r (m :: * -> *). MonadReader r m => m r
ask
        m a -> ModuleT st m a
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift (m a -> ModuleT st m a) -> m a -> ModuleT st m a
forall a b. (a -> b) -> a -> b
$ Run (ModuleT st) -> m a
f (Run (ModuleT st) -> m a) -> Run (ModuleT st) -> m a
forall a b. (a -> b) -> a -> b
$ \ModuleT st n b
t -> ModuleT st n b -> ModuleInfo st -> n b
forall st (m :: * -> *) a. ModuleT st m a -> ModuleInfo st -> m a
runModuleT ModuleT st n b
t ModuleInfo st
r
    restoreT :: m (StT (ModuleT st) a) -> ModuleT st m a
restoreT = m (StT (ModuleT st) a) -> ModuleT st m a
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift
    {-# INLINE liftWith #-}
    {-# INLINE restoreT #-}

instance MonadBaseControl b m => MonadBaseControl b (ModuleT st m) where
    type StM (ModuleT st m) a = ComposeSt (ModuleT st) m a
    liftBaseWith :: (RunInBase (ModuleT st m) b -> b a) -> ModuleT st m a
liftBaseWith = (RunInBase (ModuleT st m) b -> b a) -> ModuleT st m a
forall (t :: (* -> *) -> * -> *) (b :: * -> *) (m :: * -> *) a.
(MonadTransControl t, MonadBaseControl b m) =>
(RunInBaseDefault t m b -> b a) -> t m a
defaultLiftBaseWith
    restoreM :: StM (ModuleT st m) a -> ModuleT st m a
restoreM     = StM (ModuleT st m) a -> ModuleT st m a
forall (t :: (* -> *) -> * -> *) (b :: * -> *) (m :: * -> *) a.
(MonadTransControl t, MonadBaseControl b m) =>
ComposeSt t m a -> t m a
defaultRestoreM
    {-# INLINE liftBaseWith #-}
    {-# INLINE restoreM #-}