{-# LANGUAGE Trustworthy #-}
module Cleff.Reader
(
Reader (..)
, ask
, local
, asks
, runReader
, magnify
) where
import Cleff
import Lens.Micro (Lens', (%~), (&), (^.))
data Reader r :: Effect where
Ask :: Reader r m r
Local :: (r -> r) -> m a -> Reader r m a
makeEffect_ ''Reader
ask :: Reader r :> es => Eff es r
local :: Reader r :> es
=> (r -> r)
-> Eff es a
-> Eff es a
asks :: Reader r :> es => (r -> s) -> Eff es s
asks :: (r -> s) -> Eff es s
asks = ((r -> s) -> Eff es r -> Eff es s
forall (f :: Type -> Type) a b. Functor f => (a -> b) -> f a -> f b
<$> Eff es r
forall r (es :: [(Type -> Type) -> Type -> Type]).
(Reader r :> es) =>
Eff es r
ask)
runReader :: r -> Eff (Reader r ': es) ~> Eff es
runReader :: r -> Eff (Reader r : es) ~> Eff es
runReader r
x = Handler (Reader r) es -> Eff (Reader r : es) ~> Eff es
forall (e :: (Type -> Type) -> Type -> Type)
(es :: [(Type -> Type) -> Type -> Type]).
Handler e es -> Eff (e : es) ~> Eff es
interpret (r -> Handler (Reader r) es
forall r (es :: [(Type -> Type) -> Type -> Type]).
r -> Handler (Reader r) es
h r
x)
where
h :: r -> Handler (Reader r) es
h :: r -> Handler (Reader r) es
h r
r = \case
Reader r (Eff esSend) a
Ask -> r -> Eff es r
forall (f :: Type -> Type) a. Applicative f => a -> f a
pure r
r
Local r -> r
f Eff esSend a
m -> Handler (Reader r) es -> Eff esSend a -> Eff es a
forall (esSend :: [(Type -> Type) -> Type -> Type])
(e :: (Type -> Type) -> Type -> Type)
(es :: [(Type -> Type) -> Type -> Type]).
Handling esSend e es =>
Handler e es -> Eff esSend ~> Eff es
toEffWith (r -> Handler (Reader r) es
forall r (es :: [(Type -> Type) -> Type -> Type]).
r -> Handler (Reader r) es
h (r -> r
f r
r)) Eff esSend a
m
{-# INLINE runReader #-}
magnify :: Reader t :> es => Lens' t r -> Eff (Reader r ': es) ~> Eff es
magnify :: Lens' t r -> Eff (Reader r : es) ~> Eff es
magnify Lens' t r
field = Handler (Reader r) es -> Eff (Reader r : es) ~> Eff es
forall (e :: (Type -> Type) -> Type -> Type)
(es :: [(Type -> Type) -> Type -> Type]).
Handler e es -> Eff (e : es) ~> Eff es
interpret \case
Reader r (Eff esSend) a
Ask -> (t -> r) -> Eff es r
forall r (es :: [(Type -> Type) -> Type -> Type]) s.
(Reader r :> es) =>
(r -> s) -> Eff es s
asks (t -> Getting r t r -> r
forall s a. s -> Getting a s a -> a
^. Getting r t r
Lens' t r
field)
Local f m -> (t -> t) -> Eff es a -> Eff es a
forall r (es :: [(Type -> Type) -> Type -> Type]) a.
(Reader r :> es) =>
(r -> r) -> Eff es a -> Eff es a
local (t -> (t -> t) -> t
forall a b. a -> (a -> b) -> b
& (r -> Identity r) -> t -> Identity t
Lens' t r
field ((r -> Identity r) -> t -> Identity t) -> (r -> r) -> t -> t
forall s t a b. ASetter s t a b -> (a -> b) -> s -> t
%~ r -> r
f) (Eff es a -> Eff es a) -> Eff es a -> Eff es a
forall a b. (a -> b) -> a -> b
$ Eff esSend a -> Eff es a
forall (esSend :: [(Type -> Type) -> Type -> Type])
(e :: (Type -> Type) -> Type -> Type)
(es :: [(Type -> Type) -> Type -> Type]).
Handling esSend e es =>
Eff esSend ~> Eff es
toEff Eff esSend a
m
{-# INLINE magnify #-}