module Control.Effect.Reader
  ( -- * Effects
    Ask(..)
  , Local(..)
  , Reader

    -- * Actions
  , ask
  , asks
  , local

    -- * Interpretations
  , runAskConst

  , runAskAction

  , askToAsk

  , runReader

    -- * Simple variants
  , runAskConstSimple
  , runAskActionSimple
  , askToAskSimple

    -- * Threading constraints
  , ReaderThreads

    -- * Carriers
  , ReaderC
  ) where

import Control.Effect

import Control.Effect.Internal.Reader

import Control.Monad.Trans.Reader (ReaderT(..))


ask :: Eff (Ask i) m => m i
ask :: m i
ask = Ask i m i -> m i
forall (e :: Effect) (m :: * -> *) a.
(Member e (Derivs m), Carrier m) =>
e m a -> m a
send Ask i m i
forall i (m :: * -> *). Ask i m i
Ask
{-# INLINE ask #-}

asks :: Eff (Ask i) m => (i -> a) -> m a
asks :: (i -> a) -> m a
asks = ((i -> a) -> m i -> m a
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> m i
forall i (m :: * -> *). Eff (Ask i) m => m i
ask)
{-# INLINE asks #-}

local :: Eff (Local i) m => (i -> i) -> m a -> m a
local :: (i -> i) -> m a -> m a
local i -> i
f m a
m = Local i m a -> m a
forall (e :: Effect) (m :: * -> *) a.
(Member e (Derivs m), Carrier m) =>
e m a -> m a
send ((i -> i) -> m a -> Local i m a
forall i (m :: * -> *) a. (i -> i) -> m a -> Local i m a
Local i -> i
f m a
m)
{-# INLINE local #-}


-- | Run connected @'Ask' i@ and @'Local' i@ effects -- i.e. @'Reader' i@.
--
-- @'Derivs' ('ReaderC' i m) = 'Local' i ': 'Ask' i ': 'Derivs' m@
--
-- @'Control.Effect.Carrier.Prims'  ('ReaderC' i m) = 'Control.Effect.Type.ReaderPrim.ReaderPrim' i ': 'Control.Effect.Carrier.Prims' m@
runReader :: forall i m a p
           . ( Carrier m
             , Threaders '[ReaderThreads] m p
             )
          => i
          -> ReaderC i m a
          -> m a
runReader :: i -> ReaderC i m a -> m a
runReader i
i ReaderC i m a
m = ReaderT i m a -> i -> m a
forall r (m :: * -> *) a. ReaderT r m a -> r -> m a
runReaderT (ReaderC i m a -> ReaderT i m a
forall i (m :: * -> *) a. ReaderC i m a -> ReaderT i m a
unReaderC ReaderC i m a
m) i
i
{-# INLINE runReader #-}

-- | Run an 'Ask' effect by providing a constant to be given
-- at each use of 'ask'.
--
-- This has a higher-rank type, as it makes use of 'InterpretReifiedC'.
-- __This makes 'runAskConst' very difficult to use partially applied.__
-- __In particular, it can't be composed using @'.'@.__
--
-- If performance is secondary, consider using the slower 'runAskConstSimple',
-- which doesn't have a higher-rank type.
runAskConst :: forall i m a
             . Carrier m
            => i
            -> InterpretReifiedC (Ask i) m a
            -> m a
runAskConst :: i -> InterpretReifiedC (Ask i) m a -> m a
runAskConst i
i = EffHandler (Ask i) m -> InterpretReifiedC (Ask i) m a -> m a
forall (e :: Effect) (m :: * -> *) a.
(RepresentationalEff e, Carrier m) =>
EffHandler e m -> InterpretReifiedC e m a -> m a
interpret (EffHandler (Ask i) m -> InterpretReifiedC (Ask i) m a -> m a)
-> EffHandler (Ask i) m -> InterpretReifiedC (Ask i) m a -> m a
forall a b. (a -> b) -> a -> b
$ \case
  Ask i (Effly z) x
Ask -> i -> Effly z i
forall (m :: * -> *) a. Monad m => a -> m a
return i
i
{-# INLINE runAskConst #-}

-- | Run an 'Ask' effect by providing an action to be executed
-- at each use of 'ask'.
--
-- This has a higher-rank type, as it makes use of 'InterpretReifiedC'.
-- __This makes 'runAskAction' very difficult to use partially applied.__
-- __In particular, it can't be composed using @'.'@.__
--
-- If performance is secondary, consider using the slower 'runAskActionSimple',
-- which doesn't have a higher-rank type.
runAskAction :: forall i m a
              . Carrier m
             => m i
             -> InterpretReifiedC (Ask i) m a
             -> m a
runAskAction :: m i -> InterpretReifiedC (Ask i) m a -> m a
runAskAction m i
m = EffHandler (Ask i) m -> InterpretReifiedC (Ask i) m a -> m a
forall (e :: Effect) (m :: * -> *) a.
(RepresentationalEff e, Carrier m) =>
EffHandler e m -> InterpretReifiedC e m a -> m a
interpret (EffHandler (Ask i) m -> InterpretReifiedC (Ask i) m a -> m a)
-> EffHandler (Ask i) m -> InterpretReifiedC (Ask i) m a -> m a
forall a b. (a -> b) -> a -> b
$ \case
  Ask i (Effly z) x
Ask -> m i -> Effly z i
forall (b :: * -> *) (m :: * -> *) α. MonadBase b m => b α -> m α
liftBase m i
m
{-# INLINE runAskAction #-}

-- | Transform an @'Ask' i@ effect into an @'Ask' j@ effect by
-- providing a function to convert @j@ to @i@.
--
-- This has a higher-rank type, as it makes use of 'InterpretReifiedC'.
-- __This makes 'askToAsk' very difficult to use partially applied.__
-- __In particular, it can't be composed using @'.'@.__
--
-- If performance is secondary, consider using the slower 'askToAskSimple',
-- which doesn't have a higher-rank type.
askToAsk :: forall i j m a
          . Eff (Ask j) m
         => (j -> i)
         -> InterpretReifiedC (Ask i) m a
         -> m a
askToAsk :: (j -> i) -> InterpretReifiedC (Ask i) m a -> m a
askToAsk j -> i
f = EffHandler (Ask i) m -> InterpretReifiedC (Ask i) m a -> m a
forall (e :: Effect) (m :: * -> *) a.
(RepresentationalEff e, Carrier m) =>
EffHandler e m -> InterpretReifiedC e m a -> m a
interpret (EffHandler (Ask i) m -> InterpretReifiedC (Ask i) m a -> m a)
-> EffHandler (Ask i) m -> InterpretReifiedC (Ask i) m a -> m a
forall a b. (a -> b) -> a -> b
$ \case
  Ask i (Effly z) x
Ask -> (j -> i) -> Effly z i
forall i (m :: * -> *) a. Eff (Ask i) m => (i -> a) -> m a
asks j -> i
f
{-# INLINE askToAsk #-}

-- | Run an 'Ask' effect by providing a constant to be given
-- at each use of 'ask'
--
-- This is a less performant version of 'runAskConst' that doesn't have
-- a higher-rank type, making it much easier to use partially applied.
runAskConstSimple :: forall i m a p
                   . ( Carrier m
                     , Threaders '[ReaderThreads] m p
                     )
                  => i
                  -> InterpretSimpleC (Ask i) m a
                  -> m a
runAskConstSimple :: i -> InterpretSimpleC (Ask i) m a -> m a
runAskConstSimple i
i = EffHandler (Ask i) m -> InterpretSimpleC (Ask i) m a -> m a
forall (e :: Effect) (m :: * -> *) a (p :: [Effect]).
(RepresentationalEff e, Threaders '[ReaderThreads] m p,
 Carrier m) =>
EffHandler e m -> InterpretSimpleC e m a -> m a
interpretSimple (EffHandler (Ask i) m -> InterpretSimpleC (Ask i) m a -> m a)
-> EffHandler (Ask i) m -> InterpretSimpleC (Ask i) m a -> m a
forall a b. (a -> b) -> a -> b
$ \case
  Ask i (Effly z) x
Ask -> i -> Effly z i
forall (m :: * -> *) a. Monad m => a -> m a
return i
i
{-# INLINE runAskConstSimple #-}

-- | Run an 'Ask' effect by providing an action to be executed
-- at each use of 'ask'.
--
-- This is a less performant version of 'runAskAction' that doesn't have
-- a higher-rank type, making it much easier to use partially applied.
runAskActionSimple :: forall i m a p
                    . ( Carrier m
                      , Threaders '[ReaderThreads] m p
                      )
                   => m i
                   -> InterpretSimpleC (Ask i) m a
                   -> m a
runAskActionSimple :: m i -> InterpretSimpleC (Ask i) m a -> m a
runAskActionSimple m i
mi = EffHandler (Ask i) m -> InterpretSimpleC (Ask i) m a -> m a
forall (e :: Effect) (m :: * -> *) a (p :: [Effect]).
(RepresentationalEff e, Threaders '[ReaderThreads] m p,
 Carrier m) =>
EffHandler e m -> InterpretSimpleC e m a -> m a
interpretSimple (EffHandler (Ask i) m -> InterpretSimpleC (Ask i) m a -> m a)
-> EffHandler (Ask i) m -> InterpretSimpleC (Ask i) m a -> m a
forall a b. (a -> b) -> a -> b
$ \case
  Ask i (Effly z) x
Ask -> m i -> Effly z i
forall (b :: * -> *) (m :: * -> *) α. MonadBase b m => b α -> m α
liftBase m i
mi
{-# INLINE runAskActionSimple #-}

-- | Transform an @'Ask' i@ effect into an @'Ask' j@ effect by
-- providing a function to convert @j@ to @i@.
--
-- This is a less performant version of 'askToAsk' that doesn't have
-- a higher-rank type, making it much easier to use partially applied.
askToAskSimple :: forall i j m a p
                . ( Eff (Ask j) m
                  , Threaders '[ReaderThreads] m p
                  )
               => (j -> i)
               -> InterpretSimpleC (Ask i) m a
               -> m a
askToAskSimple :: (j -> i) -> InterpretSimpleC (Ask i) m a -> m a
askToAskSimple j -> i
f = EffHandler (Ask i) m -> InterpretSimpleC (Ask i) m a -> m a
forall (e :: Effect) (m :: * -> *) a (p :: [Effect]).
(RepresentationalEff e, Threaders '[ReaderThreads] m p,
 Carrier m) =>
EffHandler e m -> InterpretSimpleC e m a -> m a
interpretSimple (EffHandler (Ask i) m -> InterpretSimpleC (Ask i) m a -> m a)
-> EffHandler (Ask i) m -> InterpretSimpleC (Ask i) m a -> m a
forall a b. (a -> b) -> a -> b
$ \case
  Ask i (Effly z) x
Ask -> (j -> i) -> Effly z i
forall i (m :: * -> *) a. Eff (Ask i) m => (i -> a) -> m a
asks j -> i
f
{-# INLINE askToAskSimple #-}