module Effectful.Provider
(
Provider(..)
, Provider_
, runProvider
, runProvider_
, provide
, provide_
, provideWith
, provideWith_
) where
import Data.Coerce
import Data.Functor.Identity
import Data.Kind (Type)
import GHC.Stack
import Effectful
import Effectful.Dispatch.Dynamic
data Provider (e :: Effect) (input :: Type) (f :: Type -> Type) :: Effect where
ProvideWith :: input -> Eff (e : es) a -> Provider e input f (Eff es) (f a)
type Provider_ e input = Provider e input Identity
type instance DispatchOf (Provider e input f) = Dynamic
runProvider
:: forall e input f es a
. HasCallStack
=> (forall r. HasCallStack => input -> Eff (e : es) r -> Eff es (f r))
-> Eff (Provider e input f : es) a
-> Eff es a
runProvider :: forall (e :: Effect) input (f :: Type -> Type) (es :: [Effect]) a.
HasCallStack =>
(forall r. HasCallStack => input -> Eff (e : es) r -> Eff es (f r))
-> Eff (Provider e input f : es) a -> Eff es a
runProvider forall r. HasCallStack => input -> Eff (e : es) r -> Eff es (f r)
provider = EffectHandler (Provider e input f) es
-> Eff (Provider e input f : es) a -> Eff es a
forall (e :: Effect) (es :: [Effect]) a.
(HasCallStack, DispatchOf e ~ 'Dynamic) =>
EffectHandler e es -> Eff (e : es) a -> Eff es a
interpret (EffectHandler (Provider e input f) es
-> Eff (Provider e input f : es) a -> Eff es a)
-> EffectHandler (Provider e input f) es
-> Eff (Provider e input f : es) a
-> Eff es a
forall a b. (a -> b) -> a -> b
$ \LocalEnv localEs
env -> \case
ProvideWith input
input Eff (e : es) a
action -> input -> Eff (e : es) a -> Eff es (f a)
forall r. HasCallStack => input -> Eff (e : es) r -> Eff es (f r)
provider input
input (Eff (e : es) a -> Eff es (f a)) -> Eff (e : es) a -> Eff es (f a)
forall a b. (a -> b) -> a -> b
$ do
LocalEnv localEs
-> ((forall {r}. Eff localEs r -> Eff (e : es) r)
-> Eff (e : es) a)
-> Eff (e : es) a
forall (localEs :: [Effect]) (es :: [Effect]) a.
HasCallStack =>
LocalEnv localEs
-> ((forall r. Eff localEs r -> Eff es r) -> Eff es a) -> Eff es a
localSeqUnlift LocalEnv localEs
env (((forall {r}. Eff localEs r -> Eff (e : es) r) -> Eff (e : es) a)
-> Eff (e : es) a)
-> ((forall {r}. Eff localEs r -> Eff (e : es) r)
-> Eff (e : es) a)
-> Eff (e : es) a
forall a b. (a -> b) -> a -> b
$ \forall {r}. Eff localEs r -> Eff (e : es) r
unlift -> do
forall (lentEs :: [Effect]) (es :: [Effect]) (localEs :: [Effect])
a.
(HasCallStack, KnownSubset lentEs es) =>
LocalEnv localEs
-> ((forall r. Eff (lentEs ++ localEs) r -> Eff localEs r)
-> Eff es a)
-> Eff es a
localSeqLend @'[e] LocalEnv localEs
env (((forall r. Eff ('[e] ++ localEs) r -> Eff localEs r)
-> Eff (e : es) a)
-> Eff (e : es) a)
-> ((forall r. Eff ('[e] ++ localEs) r -> Eff localEs r)
-> Eff (e : es) a)
-> Eff (e : es) a
forall a b. (a -> b) -> a -> b
$ \forall r. Eff ('[e] ++ localEs) r -> Eff localEs r
lend -> do
Eff localEs a -> Eff (e : es) a
forall {r}. Eff localEs r -> Eff (e : es) r
unlift (Eff localEs a -> Eff (e : es) a)
-> (Eff (e : es) a -> Eff localEs a)
-> Eff (e : es) a
-> Eff (e : es) a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Eff (e : es) a -> Eff localEs a
Eff ('[e] ++ localEs) a -> Eff localEs a
forall r. Eff ('[e] ++ localEs) r -> Eff localEs r
lend (Eff (e : es) a -> Eff (e : es) a)
-> Eff (e : es) a -> Eff (e : es) a
forall a b. (a -> b) -> a -> b
$ Eff (e : es) a
action
runProvider_
:: forall e input es a
. HasCallStack
=> (forall r. HasCallStack => input -> Eff (e : es) r -> Eff es r)
-> Eff (Provider_ e input : es) a
-> Eff es a
runProvider_ :: forall (e :: Effect) input (es :: [Effect]) a.
HasCallStack =>
(forall r. HasCallStack => input -> Eff (e : es) r -> Eff es r)
-> Eff (Provider_ e input : es) a -> Eff es a
runProvider_ forall r. HasCallStack => input -> Eff (e : es) r -> Eff es r
provider = EffectHandler (Provider_ e input) es
-> Eff (Provider_ e input : es) a -> Eff es a
forall (e :: Effect) (es :: [Effect]) a.
(HasCallStack, DispatchOf e ~ 'Dynamic) =>
EffectHandler e es -> Eff (e : es) a -> Eff es a
interpret (EffectHandler (Provider_ e input) es
-> Eff (Provider_ e input : es) a -> Eff es a)
-> EffectHandler (Provider_ e input) es
-> Eff (Provider_ e input : es) a
-> Eff es a
forall a b. (a -> b) -> a -> b
$ \LocalEnv localEs
env -> \case
ProvideWith input
input Eff (e : es) a
action -> input -> Eff (e : es) a -> Eff es a
forall r. HasCallStack => input -> Eff (e : es) r -> Eff es r
provider input
input (Eff (e : es) a -> Eff es a) -> Eff (e : es) a -> Eff es a
forall a b. (a -> b) -> a -> b
$ do
LocalEnv localEs
-> ((forall {r}. Eff localEs r -> Eff (e : es) r)
-> Eff (e : es) a)
-> Eff (e : es) a
forall (localEs :: [Effect]) (es :: [Effect]) a.
HasCallStack =>
LocalEnv localEs
-> ((forall r. Eff localEs r -> Eff es r) -> Eff es a) -> Eff es a
localSeqUnlift LocalEnv localEs
env (((forall {r}. Eff localEs r -> Eff (e : es) r) -> Eff (e : es) a)
-> Eff (e : es) a)
-> ((forall {r}. Eff localEs r -> Eff (e : es) r)
-> Eff (e : es) a)
-> Eff (e : es) a
forall a b. (a -> b) -> a -> b
$ \forall {r}. Eff localEs r -> Eff (e : es) r
unlift -> do
forall (lentEs :: [Effect]) (es :: [Effect]) (localEs :: [Effect])
a.
(HasCallStack, KnownSubset lentEs es) =>
LocalEnv localEs
-> ((forall r. Eff (lentEs ++ localEs) r -> Eff localEs r)
-> Eff es a)
-> Eff es a
localSeqLend @'[e] LocalEnv localEs
env (((forall r. Eff ('[e] ++ localEs) r -> Eff localEs r)
-> Eff (e : es) a)
-> Eff (e : es) a)
-> ((forall r. Eff ('[e] ++ localEs) r -> Eff localEs r)
-> Eff (e : es) a)
-> Eff (e : es) a
forall a b. (a -> b) -> a -> b
$ \forall r. Eff ('[e] ++ localEs) r -> Eff localEs r
lend -> do
Eff localEs a -> Eff (e : es) a
forall {r}. Eff localEs r -> Eff (e : es) r
unlift (Eff localEs a -> Eff (e : es) a)
-> (Eff (e : localEs) (Identity a) -> Eff localEs a)
-> Eff (e : localEs) (Identity a)
-> Eff (e : es) a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Eff (e : localEs) (Identity a) -> Eff localEs a
Eff ('[e] ++ localEs) a -> Eff localEs a
forall r. Eff ('[e] ++ localEs) r -> Eff localEs r
lend (Eff (e : localEs) (Identity a) -> Eff (e : es) a)
-> Eff (e : localEs) (Identity a) -> Eff (e : es) a
forall a b. (a -> b) -> a -> b
$ Eff (e : es) a -> Eff (e : localEs) (Identity a)
forall a b. Coercible a b => a -> b
coerce Eff (e : es) a
action
provide :: (HasCallStack, Provider e () f :> es) => Eff (e : es) a -> Eff es (f a)
provide :: forall (e :: Effect) (f :: Type -> Type) (es :: [Effect]) a.
(HasCallStack, Provider e () f :> es) =>
Eff (e : es) a -> Eff es (f a)
provide = Provider e () f (Eff es) (f a) -> Eff es (f a)
forall (e :: Effect) (es :: [Effect]) a.
(HasCallStack, DispatchOf e ~ 'Dynamic, e :> es) =>
e (Eff es) a -> Eff es a
send (Provider e () f (Eff es) (f a) -> Eff es (f a))
-> (Eff (e : es) a -> Provider e () f (Eff es) (f a))
-> Eff (e : es) a
-> Eff es (f a)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. () -> Eff (e : es) a -> Provider e () f (Eff es) (f a)
forall input (e :: Effect) (es :: [Effect]) a (f :: Type -> Type).
input -> Eff (e : es) a -> Provider e input f (Eff es) (f a)
ProvideWith ()
provide_ :: (HasCallStack, Provider_ e () :> es) => Eff (e : es) a -> Eff es a
provide_ :: forall (e :: Effect) (es :: [Effect]) a.
(HasCallStack, Provider_ e () :> es) =>
Eff (e : es) a -> Eff es a
provide_ = Eff es (Identity a) -> Eff es a
forall (es :: [Effect]) a. Eff es (Identity a) -> Eff es a
dropIdentity (Eff es (Identity a) -> Eff es a)
-> (Eff (e : es) a -> Eff es (Identity a))
-> Eff (e : es) a
-> Eff es a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Provider e () Identity (Eff es) (Identity a) -> Eff es (Identity a)
forall (e :: Effect) (es :: [Effect]) a.
(HasCallStack, DispatchOf e ~ 'Dynamic, e :> es) =>
e (Eff es) a -> Eff es a
send (Provider e () Identity (Eff es) (Identity a)
-> Eff es (Identity a))
-> (Eff (e : es) a -> Provider e () Identity (Eff es) (Identity a))
-> Eff (e : es) a
-> Eff es (Identity a)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ()
-> Eff (e : es) a -> Provider e () Identity (Eff es) (Identity a)
forall input (e :: Effect) (es :: [Effect]) a (f :: Type -> Type).
input -> Eff (e : es) a -> Provider e input f (Eff es) (f a)
ProvideWith ()
provideWith
:: (HasCallStack, Provider e input f :> es)
=> input
-> Eff (e : es) a
-> Eff es (f a)
provideWith :: forall (e :: Effect) input (f :: Type -> Type) (es :: [Effect]) a.
(HasCallStack, Provider e input f :> es) =>
input -> Eff (e : es) a -> Eff es (f a)
provideWith input
input = Provider e input f (Eff es) (f a) -> Eff es (f a)
forall (e :: Effect) (es :: [Effect]) a.
(HasCallStack, DispatchOf e ~ 'Dynamic, e :> es) =>
e (Eff es) a -> Eff es a
send (Provider e input f (Eff es) (f a) -> Eff es (f a))
-> (Eff (e : es) a -> Provider e input f (Eff es) (f a))
-> Eff (e : es) a
-> Eff es (f a)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. input -> Eff (e : es) a -> Provider e input f (Eff es) (f a)
forall input (e :: Effect) (es :: [Effect]) a (f :: Type -> Type).
input -> Eff (e : es) a -> Provider e input f (Eff es) (f a)
ProvideWith input
input
provideWith_
:: (HasCallStack, Provider_ e input :> es)
=> input
-> Eff (e : es) a
-> Eff es a
provideWith_ :: forall (e :: Effect) input (es :: [Effect]) a.
(HasCallStack, Provider_ e input :> es) =>
input -> Eff (e : es) a -> Eff es a
provideWith_ input
input = Eff es (Identity a) -> Eff es a
forall (es :: [Effect]) a. Eff es (Identity a) -> Eff es a
dropIdentity (Eff es (Identity a) -> Eff es a)
-> (Eff (e : es) a -> Eff es (Identity a))
-> Eff (e : es) a
-> Eff es a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Provider e input Identity (Eff es) (Identity a)
-> Eff es (Identity a)
forall (e :: Effect) (es :: [Effect]) a.
(HasCallStack, DispatchOf e ~ 'Dynamic, e :> es) =>
e (Eff es) a -> Eff es a
send (Provider e input Identity (Eff es) (Identity a)
-> Eff es (Identity a))
-> (Eff (e : es) a
-> Provider e input Identity (Eff es) (Identity a))
-> Eff (e : es) a
-> Eff es (Identity a)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. input
-> Eff (e : es) a
-> Provider e input Identity (Eff es) (Identity a)
forall input (e :: Effect) (es :: [Effect]) a (f :: Type -> Type).
input -> Eff (e : es) a -> Provider e input f (Eff es) (f a)
ProvideWith input
input
dropIdentity :: Eff es (Identity a) -> Eff es a
dropIdentity :: forall (es :: [Effect]) a. Eff es (Identity a) -> Eff es a
dropIdentity = Eff es (Identity a) -> Eff es a
forall a b. Coercible a b => a -> b
coerce