-- | The 'Reader' as an effect.
module Effectful.Reader
  ( Reader
  , runReader
  , ask
  , local
  , reader
  , asks
  ) where

import Effectful.Internal.Has
import Effectful.Internal.Monad

-- | Provide access to a read only value of type @r@.
newtype Reader r = Reader { Reader r -> r
unReader :: r }

runReader :: r -> Eff (Reader r : es) a -> Eff es a
runReader :: r -> Eff (Reader r : es) a -> Eff es a
runReader r
r = Reader r -> Eff (Reader r : es) a -> Eff es a
forall e (es :: [*]) a. e -> Eff (e : es) a -> Eff es a
evalEffect (r -> Reader r
forall r. r -> Reader r
Reader r
r)

ask :: Reader r :> es => Eff es r
ask :: Eff es r
ask = Reader r -> r
forall r. Reader r -> r
unReader (Reader r -> r) -> Eff es (Reader r) -> Eff es r
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Eff es (Reader r)
forall e (es :: [*]). (e :> es) => Eff es e
getEffect

local :: Reader r :> es => (r -> r) -> Eff es a -> Eff es a
local :: (r -> r) -> Eff es a -> Eff es a
local r -> r
f = (Reader r -> Reader r) -> Eff es a -> Eff es a
forall e (es :: [*]) a.
(e :> es) =>
(e -> e) -> Eff es a -> Eff es a
localEffect (r -> Reader r
forall r. r -> Reader r
Reader (r -> Reader r) -> (Reader r -> r) -> Reader r -> Reader r
forall b c a. (b -> c) -> (a -> b) -> a -> c
. r -> r
f (r -> r) -> (Reader r -> r) -> Reader r -> r
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Reader r -> r
forall r. Reader r -> r
unReader)

reader :: Reader r :> es => (r -> a) -> Eff es a
reader :: (r -> a) -> Eff es a
reader r -> a
f = r -> a
f (r -> a) -> (Reader r -> r) -> Reader r -> a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Reader r -> r
forall r. Reader r -> r
unReader (Reader r -> a) -> Eff es (Reader r) -> Eff es a
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Eff es (Reader r)
forall e (es :: [*]). (e :> es) => Eff es e
getEffect

asks :: Reader r :> es => (r -> a) -> Eff es a
asks :: (r -> a) -> Eff es a
asks = (r -> a) -> Eff es a
forall r (es :: [*]) a. (Reader r :> es) => (r -> a) -> Eff es a
reader