{-# OPTIONS_HADDOCK not-home #-}
module Control.Effect.Internal.Reader where
import Data.Coerce
import Control.Effect
import Control.Effect.Carrier
import Control.Effect.Type.ReaderPrim
import Control.Monad.Trans.Reader (ReaderT(..))
import qualified Control.Monad.Trans.Reader as R
data Ask i m a where
Ask :: Ask i m i
data Local i m a where
Local :: (i -> i) -> m a -> Local i m a
type Reader i = Bundle [Local i, Ask i]
newtype ReaderC i m a = ReaderC {
unReaderC :: ReaderT i m a
}
deriving ( Functor, Applicative, Monad
, Alternative, MonadPlus
, MonadFix, MonadFail, MonadIO
, MonadThrow, MonadCatch, MonadMask
, MonadBase b, MonadBaseControl b
)
deriving (MonadTrans, MonadTransControl)
instance ( Threads (ReaderT i) (Prims m)
, Carrier m
)
=> Carrier (ReaderC i m) where
type Derivs (ReaderC i m) = Local i ': Ask i ': Derivs m
type Prims (ReaderC i m) = ReaderPrim i ': Prims m
algPrims = powerAlg (coerce (thread @(ReaderT i) (algPrims @m))) $ \case
ReaderPrimAsk -> ReaderC R.ask
ReaderPrimLocal f (ReaderC m) -> ReaderC (R.local f m)
{-# INLINEABLE algPrims #-}
reformulate n alg =
powerAlg (
powerAlg (
reformulate (n . lift) (weakenAlg alg)
) $ \case
Ask -> n (ReaderC R.ask)
) $ \case
Local f m -> (alg . inj) $ ReaderPrimLocal f m
{-# INLINEABLE reformulate #-}