{-# LANGUAGE ImplicitParams #-}
{-# LANGUAGE UndecidableInstances #-}
module Effectful.Dispatch.Dynamic
(
send
, EffectHandler
, interpret
, reinterpret
, interpose
, impose
, LocalEnv
, localSeqUnlift
, localSeqUnliftIO
, localUnlift
, localUnliftIO
, localSeqLift
, localLift
, withLiftMap
, withLiftMapIO
, localLiftUnlift
, localLiftUnliftIO
, localSeqLend
, localLend
, localSeqBorrow
, localBorrow
, SharedSuffix
, HasCallStack
) where
import Control.Monad
import Control.Monad.IO.Unlift
import Data.Primitive.PrimArray
import GHC.Stack (HasCallStack)
import GHC.TypeLits
import Effectful.Internal.Effect
import Effectful.Internal.Env
import Effectful.Internal.Monad
import Effectful.Internal.Utils
interpret
:: DispatchOf e ~ Dynamic
=> EffectHandler e es
-> Eff (e : es) a
-> Eff es a
interpret :: forall (e :: Effect) (es :: [Effect]) a.
(DispatchOf e ~ 'Dynamic) =>
EffectHandler e es -> Eff (e : es) a -> Eff es a
interpret EffectHandler e es
handler Eff (e : es) a
m = (Env es -> IO a) -> Eff es a
forall (es :: [Effect]) a. (Env es -> IO a) -> Eff es a
unsafeEff ((Env es -> IO a) -> Eff es a) -> (Env es -> IO a) -> Eff es a
forall a b. (a -> b) -> a -> b
$ \Env es
es -> do
(Eff es a -> Env es -> IO a
forall (es :: [Effect]) a. Eff es a -> Env es -> IO a
`unEff` Env es
es) (Eff es a -> IO a) -> Eff es a -> IO a
forall a b. (a -> b) -> a -> b
$ Handler e -> Eff (e : es) a -> Eff es a
forall (e :: Effect) (es :: [Effect]) a.
(DispatchOf e ~ 'Dynamic) =>
Handler e -> Eff (e : es) a -> Eff es a
runHandler (Env es -> Handler e
mkHandler Env es
es) Eff (e : es) a
m
where
mkHandler :: Env es -> Handler e
mkHandler Env es
es = Env es -> EffectHandler e es -> Handler e
forall (handlerEs :: [Effect]) (a :: Effect).
Env handlerEs -> EffectHandler a handlerEs -> Handler a
Handler Env es
es (let ?callStack = CallStack -> CallStack
thawCallStack HasCallStack
CallStack
?callStack in LocalEnv localEs es -> e (Eff localEs) a -> Eff es a
EffectHandler e es
handler)
reinterpret
:: DispatchOf e ~ Dynamic
=> (Eff handlerEs a -> Eff es b)
-> EffectHandler e handlerEs
-> Eff (e : es) a
-> Eff es b
reinterpret :: forall (e :: Effect) (handlerEs :: [Effect]) a (es :: [Effect]) b.
(DispatchOf e ~ 'Dynamic) =>
(Eff handlerEs a -> Eff es b)
-> EffectHandler e handlerEs -> Eff (e : es) a -> Eff es b
reinterpret Eff handlerEs a -> Eff es b
runHandlerEs EffectHandler e handlerEs
handler Eff (e : es) a
m = (Env es -> IO b) -> Eff es b
forall (es :: [Effect]) a. (Env es -> IO a) -> Eff es a
unsafeEff ((Env es -> IO b) -> Eff es b) -> (Env es -> IO b) -> Eff es b
forall a b. (a -> b) -> a -> b
$ \Env es
es -> do
(Eff es b -> Env es -> IO b
forall (es :: [Effect]) a. Eff es a -> Env es -> IO a
`unEff` Env es
es) (Eff es b -> IO b)
-> ((Env handlerEs -> IO a) -> Eff es b)
-> (Env handlerEs -> IO a)
-> IO b
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Eff handlerEs a -> Eff es b
runHandlerEs (Eff handlerEs a -> Eff es b)
-> ((Env handlerEs -> IO a) -> Eff handlerEs a)
-> (Env handlerEs -> IO a)
-> Eff es b
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Env handlerEs -> IO a) -> Eff handlerEs a
forall (es :: [Effect]) a. (Env es -> IO a) -> Eff es a
unsafeEff ((Env handlerEs -> IO a) -> IO b)
-> (Env handlerEs -> IO a) -> IO b
forall a b. (a -> b) -> a -> b
$ \Env handlerEs
handlerEs -> do
(Eff es a -> Env es -> IO a
forall (es :: [Effect]) a. Eff es a -> Env es -> IO a
`unEff` Env es
es) (Eff es a -> IO a) -> Eff es a -> IO a
forall a b. (a -> b) -> a -> b
$ Handler e -> Eff (e : es) a -> Eff es a
forall (e :: Effect) (es :: [Effect]) a.
(DispatchOf e ~ 'Dynamic) =>
Handler e -> Eff (e : es) a -> Eff es a
runHandler (Env handlerEs -> Handler e
mkHandler Env handlerEs
handlerEs) Eff (e : es) a
m
where
mkHandler :: Env handlerEs -> Handler e
mkHandler Env handlerEs
es = Env handlerEs -> EffectHandler e handlerEs -> Handler e
forall (handlerEs :: [Effect]) (a :: Effect).
Env handlerEs -> EffectHandler a handlerEs -> Handler a
Handler Env handlerEs
es (let ?callStack = CallStack -> CallStack
thawCallStack HasCallStack
CallStack
?callStack in LocalEnv localEs handlerEs -> e (Eff localEs) a -> Eff handlerEs a
EffectHandler e handlerEs
handler)
interpose
:: forall e es a. (DispatchOf e ~ Dynamic, e :> es)
=> EffectHandler e es
-> Eff es a
-> Eff es a
interpose :: forall (e :: Effect) (es :: [Effect]) a.
(DispatchOf e ~ 'Dynamic, e :> es) =>
EffectHandler e es -> Eff es a -> Eff es a
interpose EffectHandler e es
handler Eff es a
m = (Env es -> IO a) -> Eff es a
forall (es :: [Effect]) a. (Env es -> IO a) -> Eff es a
unsafeEff ((Env es -> IO a) -> Eff es a) -> (Env es -> IO a) -> Eff es a
forall a b. (a -> b) -> a -> b
$ \Env es
es -> do
IO (Env es) -> (Env es -> IO ()) -> (Env es -> IO a) -> IO a
forall a b c. IO a -> (a -> IO b) -> (a -> IO c) -> IO c
inlineBracket
(do
Handler e
origHandler <- forall (e :: Effect) (es :: [Effect]).
(e :> es) =>
Env es -> IO (EffectRep (DispatchOf e) e)
getEnv @e Env es
es
EffectRep (DispatchOf e) e
-> Relinker (EffectRep (DispatchOf e)) e -> Env es -> IO (Env es)
forall (e :: Effect) (es :: [Effect]).
(e :> es) =>
EffectRep (DispatchOf e) e
-> Relinker (EffectRep (DispatchOf e)) e -> Env es -> IO (Env es)
replaceEnv EffectRep (DispatchOf e) e
Handler e
origHandler Relinker (EffectRep (DispatchOf e)) e
Relinker Handler e
forall (e :: Effect). Relinker Handler e
relinkHandler Env es
es
)
(\Env es
newEs -> do
Env es -> EffectRep (DispatchOf e) e -> IO ()
forall (e :: Effect) (es :: [Effect]).
(e :> es) =>
Env es -> EffectRep (DispatchOf e) e -> IO ()
putEnv Env es
es (EffectRep (DispatchOf e) e -> IO ())
-> IO (EffectRep (DispatchOf e) e) -> IO ()
forall (m :: Type -> Type) a b. Monad m => (a -> m b) -> m a -> m b
=<< forall (e :: Effect) (es :: [Effect]).
(e :> es) =>
Env es -> IO (EffectRep (DispatchOf e) e)
getEnv @e Env es
newEs
forall (e :: Effect) (es :: [Effect]). (e :> es) => Env es -> IO ()
unreplaceEnv @e Env es
newEs
)
(\Env es
newEs -> do
Env es -> EffectRep (DispatchOf e) e -> IO ()
forall (e :: Effect) (es :: [Effect]).
(e :> es) =>
Env es -> EffectRep (DispatchOf e) e -> IO ()
putEnv Env es
es (EffectRep (DispatchOf e) e -> IO ())
-> EffectRep (DispatchOf e) e -> IO ()
forall a b. (a -> b) -> a -> b
$ Env es -> Handler e
mkHandler Env es
newEs
Eff es a -> Env es -> IO a
forall (es :: [Effect]) a. Eff es a -> Env es -> IO a
unEff Eff es a
m Env es
es
)
where
mkHandler :: Env es -> Handler e
mkHandler Env es
es = Env es -> EffectHandler e es -> Handler e
forall (handlerEs :: [Effect]) (a :: Effect).
Env handlerEs -> EffectHandler a handlerEs -> Handler a
Handler Env es
es (let ?callStack = CallStack -> CallStack
thawCallStack HasCallStack
CallStack
?callStack in LocalEnv localEs es -> e (Eff localEs) a -> Eff es a
EffectHandler e es
handler)
impose
:: forall e es handlerEs a b. (DispatchOf e ~ Dynamic, e :> es)
=> (Eff handlerEs a -> Eff es b)
-> EffectHandler e handlerEs
-> Eff es a
-> Eff es b
impose :: forall (e :: Effect) (es :: [Effect]) (handlerEs :: [Effect]) a b.
(DispatchOf e ~ 'Dynamic, e :> es) =>
(Eff handlerEs a -> Eff es b)
-> EffectHandler e handlerEs -> Eff es a -> Eff es b
impose Eff handlerEs a -> Eff es b
runHandlerEs EffectHandler e handlerEs
handler Eff es a
m = (Env es -> IO b) -> Eff es b
forall (es :: [Effect]) a. (Env es -> IO a) -> Eff es a
unsafeEff ((Env es -> IO b) -> Eff es b) -> (Env es -> IO b) -> Eff es b
forall a b. (a -> b) -> a -> b
$ \Env es
es -> do
IO (Env es) -> (Env es -> IO ()) -> (Env es -> IO b) -> IO b
forall a b c. IO a -> (a -> IO b) -> (a -> IO c) -> IO c
inlineBracket
(do
Handler e
origHandler <- forall (e :: Effect) (es :: [Effect]).
(e :> es) =>
Env es -> IO (EffectRep (DispatchOf e) e)
getEnv @e Env es
es
EffectRep (DispatchOf e) e
-> Relinker (EffectRep (DispatchOf e)) e -> Env es -> IO (Env es)
forall (e :: Effect) (es :: [Effect]).
(e :> es) =>
EffectRep (DispatchOf e) e
-> Relinker (EffectRep (DispatchOf e)) e -> Env es -> IO (Env es)
replaceEnv EffectRep (DispatchOf e) e
Handler e
origHandler Relinker (EffectRep (DispatchOf e)) e
Relinker Handler e
forall (e :: Effect). Relinker Handler e
relinkHandler Env es
es
)
(\Env es
newEs -> do
Env es -> EffectRep (DispatchOf e) e -> IO ()
forall (e :: Effect) (es :: [Effect]).
(e :> es) =>
Env es -> EffectRep (DispatchOf e) e -> IO ()
putEnv Env es
es (EffectRep (DispatchOf e) e -> IO ())
-> IO (EffectRep (DispatchOf e) e) -> IO ()
forall (m :: Type -> Type) a b. Monad m => (a -> m b) -> m a -> m b
=<< forall (e :: Effect) (es :: [Effect]).
(e :> es) =>
Env es -> IO (EffectRep (DispatchOf e) e)
getEnv @e Env es
newEs
forall (e :: Effect) (es :: [Effect]). (e :> es) => Env es -> IO ()
unreplaceEnv @e Env es
newEs
)
(\Env es
newEs -> do
(Eff es b -> Env es -> IO b
forall (es :: [Effect]) a. Eff es a -> Env es -> IO a
`unEff` Env es
newEs) (Eff es b -> IO b)
-> ((Env handlerEs -> IO a) -> Eff es b)
-> (Env handlerEs -> IO a)
-> IO b
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Eff handlerEs a -> Eff es b
runHandlerEs (Eff handlerEs a -> Eff es b)
-> ((Env handlerEs -> IO a) -> Eff handlerEs a)
-> (Env handlerEs -> IO a)
-> Eff es b
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Env handlerEs -> IO a) -> Eff handlerEs a
forall (es :: [Effect]) a. (Env es -> IO a) -> Eff es a
unsafeEff ((Env handlerEs -> IO a) -> IO b)
-> (Env handlerEs -> IO a) -> IO b
forall a b. (a -> b) -> a -> b
$ \Env handlerEs
handlerEs -> do
Env es -> EffectRep (DispatchOf e) e -> IO ()
forall (e :: Effect) (es :: [Effect]).
(e :> es) =>
Env es -> EffectRep (DispatchOf e) e -> IO ()
putEnv Env es
es (EffectRep (DispatchOf e) e -> IO ())
-> EffectRep (DispatchOf e) e -> IO ()
forall a b. (a -> b) -> a -> b
$ Env handlerEs -> Handler e
mkHandler Env handlerEs
handlerEs
Eff es a -> Env es -> IO a
forall (es :: [Effect]) a. Eff es a -> Env es -> IO a
unEff Eff es a
m Env es
es
)
where
mkHandler :: Env handlerEs -> Handler e
mkHandler Env handlerEs
es = Env handlerEs -> EffectHandler e handlerEs -> Handler e
forall (handlerEs :: [Effect]) (a :: Effect).
Env handlerEs -> EffectHandler a handlerEs -> Handler a
Handler Env handlerEs
es (let ?callStack = CallStack -> CallStack
thawCallStack HasCallStack
CallStack
?callStack in LocalEnv localEs handlerEs -> e (Eff localEs) a -> Eff handlerEs a
EffectHandler e handlerEs
handler)
localSeqUnlift
:: (HasCallStack, SharedSuffix es handlerEs)
=> LocalEnv localEs handlerEs
-> ((forall r. Eff localEs r -> Eff es r) -> Eff es a)
-> Eff es a
localSeqUnlift :: forall (es :: [Effect]) (handlerEs :: [Effect])
(localEs :: [Effect]) a.
(HasCallStack, SharedSuffix es handlerEs) =>
LocalEnv localEs handlerEs
-> ((forall r. Eff localEs r -> Eff es r) -> Eff es a) -> Eff es a
localSeqUnlift (LocalEnv Env localEs
les) (forall r. Eff localEs r -> Eff es r) -> Eff es a
k = (Env es -> IO a) -> Eff es a
forall (es :: [Effect]) a. (Env es -> IO a) -> Eff es a
unsafeEff ((Env es -> IO a) -> Eff es a) -> (Env es -> IO a) -> Eff es a
forall a b. (a -> b) -> a -> b
$ \Env es
es -> do
Env localEs -> ((forall r. Eff localEs r -> IO r) -> IO a) -> IO a
forall (es :: [Effect]) a.
HasCallStack =>
Env es -> ((forall r. Eff es r -> IO r) -> IO a) -> IO a
seqUnliftIO Env localEs
les (((forall r. Eff localEs r -> IO r) -> IO a) -> IO a)
-> ((forall r. Eff localEs r -> IO r) -> IO a) -> IO a
forall a b. (a -> b) -> a -> b
$ \forall r. Eff localEs r -> IO r
unlift -> do
(Eff es a -> Env es -> IO a
forall (es :: [Effect]) a. Eff es a -> Env es -> IO a
`unEff` Env es
es) (Eff es a -> IO a) -> Eff es a -> IO a
forall a b. (a -> b) -> a -> b
$ (forall r. Eff localEs r -> Eff es r) -> Eff es a
k ((forall r. Eff localEs r -> Eff es r) -> Eff es a)
-> (forall r. Eff localEs r -> Eff es r) -> Eff es a
forall a b. (a -> b) -> a -> b
$ IO r -> Eff es r
forall a (es :: [Effect]). IO a -> Eff es a
unsafeEff_ (IO r -> Eff es r)
-> (Eff localEs r -> IO r) -> Eff localEs r -> Eff es r
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Eff localEs r -> IO r
forall r. Eff localEs r -> IO r
unlift
localSeqUnliftIO
:: (HasCallStack, SharedSuffix es handlerEs, IOE :> es)
=> LocalEnv localEs handlerEs
-> ((forall r. Eff localEs r -> IO r) -> IO a)
-> Eff es a
localSeqUnliftIO :: forall (es :: [Effect]) (handlerEs :: [Effect])
(localEs :: [Effect]) a.
(HasCallStack, SharedSuffix es handlerEs, IOE :> es) =>
LocalEnv localEs handlerEs
-> ((forall r. Eff localEs r -> IO r) -> IO a) -> Eff es a
localSeqUnliftIO (LocalEnv Env localEs
les) (forall r. Eff localEs r -> IO r) -> IO a
k = IO a -> Eff es a
forall a. IO a -> Eff es a
forall (m :: Type -> Type) a. MonadIO m => IO a -> m a
liftIO (IO a -> Eff es a) -> IO a -> Eff es a
forall a b. (a -> b) -> a -> b
$ Env localEs -> ((forall r. Eff localEs r -> IO r) -> IO a) -> IO a
forall (es :: [Effect]) a.
HasCallStack =>
Env es -> ((forall r. Eff es r -> IO r) -> IO a) -> IO a
seqUnliftIO Env localEs
les (forall r. Eff localEs r -> IO r) -> IO a
k
localUnlift
:: (HasCallStack, SharedSuffix es handlerEs)
=> LocalEnv localEs handlerEs
-> UnliftStrategy
-> ((forall r. Eff localEs r -> Eff es r) -> Eff es a)
-> Eff es a
localUnlift :: forall (es :: [Effect]) (handlerEs :: [Effect])
(localEs :: [Effect]) a.
(HasCallStack, SharedSuffix es handlerEs) =>
LocalEnv localEs handlerEs
-> UnliftStrategy
-> ((forall r. Eff localEs r -> Eff es r) -> Eff es a)
-> Eff es a
localUnlift (LocalEnv Env localEs
les) UnliftStrategy
strategy (forall r. Eff localEs r -> Eff es r) -> Eff es a
k = case UnliftStrategy
strategy of
UnliftStrategy
SeqUnlift -> (Env es -> IO a) -> Eff es a
forall (es :: [Effect]) a. (Env es -> IO a) -> Eff es a
unsafeEff ((Env es -> IO a) -> Eff es a) -> (Env es -> IO a) -> Eff es a
forall a b. (a -> b) -> a -> b
$ \Env es
es -> do
Env localEs -> ((forall r. Eff localEs r -> IO r) -> IO a) -> IO a
forall (es :: [Effect]) a.
HasCallStack =>
Env es -> ((forall r. Eff es r -> IO r) -> IO a) -> IO a
seqUnliftIO Env localEs
les (((forall r. Eff localEs r -> IO r) -> IO a) -> IO a)
-> ((forall r. Eff localEs r -> IO r) -> IO a) -> IO a
forall a b. (a -> b) -> a -> b
$ \forall r. Eff localEs r -> IO r
unlift -> do
(Eff es a -> Env es -> IO a
forall (es :: [Effect]) a. Eff es a -> Env es -> IO a
`unEff` Env es
es) (Eff es a -> IO a) -> Eff es a -> IO a
forall a b. (a -> b) -> a -> b
$ (forall r. Eff localEs r -> Eff es r) -> Eff es a
k ((forall r. Eff localEs r -> Eff es r) -> Eff es a)
-> (forall r. Eff localEs r -> Eff es r) -> Eff es a
forall a b. (a -> b) -> a -> b
$ IO r -> Eff es r
forall a (es :: [Effect]). IO a -> Eff es a
unsafeEff_ (IO r -> Eff es r)
-> (Eff localEs r -> IO r) -> Eff localEs r -> Eff es r
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Eff localEs r -> IO r
forall r. Eff localEs r -> IO r
unlift
ConcUnlift Persistence
p Limit
l -> (Env es -> IO a) -> Eff es a
forall (es :: [Effect]) a. (Env es -> IO a) -> Eff es a
unsafeEff ((Env es -> IO a) -> Eff es a) -> (Env es -> IO a) -> Eff es a
forall a b. (a -> b) -> a -> b
$ \Env es
es -> do
Env localEs
-> Persistence
-> Limit
-> ((forall r. Eff localEs r -> IO r) -> IO a)
-> IO a
forall (es :: [Effect]) a.
HasCallStack =>
Env es
-> Persistence
-> Limit
-> ((forall r. Eff es r -> IO r) -> IO a)
-> IO a
concUnliftIO Env localEs
les Persistence
p Limit
l (((forall r. Eff localEs r -> IO r) -> IO a) -> IO a)
-> ((forall r. Eff localEs r -> IO r) -> IO a) -> IO a
forall a b. (a -> b) -> a -> b
$ \forall r. Eff localEs r -> IO r
unlift -> do
(Eff es a -> Env es -> IO a
forall (es :: [Effect]) a. Eff es a -> Env es -> IO a
`unEff` Env es
es) (Eff es a -> IO a) -> Eff es a -> IO a
forall a b. (a -> b) -> a -> b
$ (forall r. Eff localEs r -> Eff es r) -> Eff es a
k ((forall r. Eff localEs r -> Eff es r) -> Eff es a)
-> (forall r. Eff localEs r -> Eff es r) -> Eff es a
forall a b. (a -> b) -> a -> b
$ IO r -> Eff es r
forall a (es :: [Effect]). IO a -> Eff es a
unsafeEff_ (IO r -> Eff es r)
-> (Eff localEs r -> IO r) -> Eff localEs r -> Eff es r
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Eff localEs r -> IO r
forall r. Eff localEs r -> IO r
unlift
{-# INLINE localUnlift #-}
localUnliftIO
:: (HasCallStack, SharedSuffix es handlerEs, IOE :> es)
=> LocalEnv localEs handlerEs
-> UnliftStrategy
-> ((forall r. Eff localEs r -> IO r) -> IO a)
-> Eff es a
localUnliftIO :: forall (es :: [Effect]) (handlerEs :: [Effect])
(localEs :: [Effect]) a.
(HasCallStack, SharedSuffix es handlerEs, IOE :> es) =>
LocalEnv localEs handlerEs
-> UnliftStrategy
-> ((forall r. Eff localEs r -> IO r) -> IO a)
-> Eff es a
localUnliftIO (LocalEnv Env localEs
les) UnliftStrategy
strategy (forall r. Eff localEs r -> IO r) -> IO a
k = case UnliftStrategy
strategy of
UnliftStrategy
SeqUnlift -> IO a -> Eff es a
forall a. IO a -> Eff es a
forall (m :: Type -> Type) a. MonadIO m => IO a -> m a
liftIO (IO a -> Eff es a) -> IO a -> Eff es a
forall a b. (a -> b) -> a -> b
$ Env localEs -> ((forall r. Eff localEs r -> IO r) -> IO a) -> IO a
forall (es :: [Effect]) a.
HasCallStack =>
Env es -> ((forall r. Eff es r -> IO r) -> IO a) -> IO a
seqUnliftIO Env localEs
les (forall r. Eff localEs r -> IO r) -> IO a
k
ConcUnlift Persistence
p Limit
l -> IO a -> Eff es a
forall a. IO a -> Eff es a
forall (m :: Type -> Type) a. MonadIO m => IO a -> m a
liftIO (IO a -> Eff es a) -> IO a -> Eff es a
forall a b. (a -> b) -> a -> b
$ Env localEs
-> Persistence
-> Limit
-> ((forall r. Eff localEs r -> IO r) -> IO a)
-> IO a
forall (es :: [Effect]) a.
HasCallStack =>
Env es
-> Persistence
-> Limit
-> ((forall r. Eff es r -> IO r) -> IO a)
-> IO a
concUnliftIO Env localEs
les Persistence
p Limit
l (forall r. Eff localEs r -> IO r) -> IO a
k
{-# INLINE localUnliftIO #-}
localSeqLift
:: (HasCallStack, SharedSuffix es handlerEs)
=> LocalEnv localEs handlerEs
-> ((forall r. Eff es r -> Eff localEs r) -> Eff es a)
-> Eff es a
localSeqLift :: forall (es :: [Effect]) (handlerEs :: [Effect])
(localEs :: [Effect]) a.
(HasCallStack, SharedSuffix es handlerEs) =>
LocalEnv localEs handlerEs
-> ((forall r. Eff es r -> Eff localEs r) -> Eff es a) -> Eff es a
localSeqLift !LocalEnv localEs handlerEs
_ (forall r. Eff es r -> Eff localEs r) -> Eff es a
k = (Env es -> IO a) -> Eff es a
forall (es :: [Effect]) a. (Env es -> IO a) -> Eff es a
unsafeEff ((Env es -> IO a) -> Eff es a) -> (Env es -> IO a) -> Eff es a
forall a b. (a -> b) -> a -> b
$ \Env es
es -> do
Env es -> ((forall r. Eff es r -> IO r) -> IO a) -> IO a
forall (es :: [Effect]) a.
HasCallStack =>
Env es -> ((forall r. Eff es r -> IO r) -> IO a) -> IO a
seqUnliftIO Env es
es (((forall r. Eff es r -> IO r) -> IO a) -> IO a)
-> ((forall r. Eff es r -> IO r) -> IO a) -> IO a
forall a b. (a -> b) -> a -> b
$ \forall r. Eff es r -> IO r
unlift -> do
(Eff es a -> Env es -> IO a
forall (es :: [Effect]) a. Eff es a -> Env es -> IO a
`unEff` Env es
es) (Eff es a -> IO a) -> Eff es a -> IO a
forall a b. (a -> b) -> a -> b
$ (forall r. Eff es r -> Eff localEs r) -> Eff es a
k ((forall r. Eff es r -> Eff localEs r) -> Eff es a)
-> (forall r. Eff es r -> Eff localEs r) -> Eff es a
forall a b. (a -> b) -> a -> b
$ IO r -> Eff localEs r
forall a (es :: [Effect]). IO a -> Eff es a
unsafeEff_ (IO r -> Eff localEs r)
-> (Eff es r -> IO r) -> Eff es r -> Eff localEs r
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Eff es r -> IO r
forall r. Eff es r -> IO r
unlift
localLift
:: (HasCallStack, SharedSuffix es handlerEs)
=> LocalEnv localEs handlerEs
-> UnliftStrategy
-> ((forall r. Eff es r -> Eff localEs r) -> Eff es a)
-> Eff es a
localLift :: forall (es :: [Effect]) (handlerEs :: [Effect])
(localEs :: [Effect]) a.
(HasCallStack, SharedSuffix es handlerEs) =>
LocalEnv localEs handlerEs
-> UnliftStrategy
-> ((forall r. Eff es r -> Eff localEs r) -> Eff es a)
-> Eff es a
localLift !LocalEnv localEs handlerEs
_ UnliftStrategy
strategy (forall r. Eff es r -> Eff localEs r) -> Eff es a
k = case UnliftStrategy
strategy of
UnliftStrategy
SeqUnlift -> (Env es -> IO a) -> Eff es a
forall (es :: [Effect]) a. (Env es -> IO a) -> Eff es a
unsafeEff ((Env es -> IO a) -> Eff es a) -> (Env es -> IO a) -> Eff es a
forall a b. (a -> b) -> a -> b
$ \Env es
es -> do
Env es -> ((forall r. Eff es r -> IO r) -> IO a) -> IO a
forall (es :: [Effect]) a.
HasCallStack =>
Env es -> ((forall r. Eff es r -> IO r) -> IO a) -> IO a
seqUnliftIO Env es
es (((forall r. Eff es r -> IO r) -> IO a) -> IO a)
-> ((forall r. Eff es r -> IO r) -> IO a) -> IO a
forall a b. (a -> b) -> a -> b
$ \forall r. Eff es r -> IO r
unlift -> do
(Eff es a -> Env es -> IO a
forall (es :: [Effect]) a. Eff es a -> Env es -> IO a
`unEff` Env es
es) (Eff es a -> IO a) -> Eff es a -> IO a
forall a b. (a -> b) -> a -> b
$ (forall r. Eff es r -> Eff localEs r) -> Eff es a
k ((forall r. Eff es r -> Eff localEs r) -> Eff es a)
-> (forall r. Eff es r -> Eff localEs r) -> Eff es a
forall a b. (a -> b) -> a -> b
$ IO r -> Eff localEs r
forall a (es :: [Effect]). IO a -> Eff es a
unsafeEff_ (IO r -> Eff localEs r)
-> (Eff es r -> IO r) -> Eff es r -> Eff localEs r
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Eff es r -> IO r
forall r. Eff es r -> IO r
unlift
ConcUnlift Persistence
p Limit
l -> (Env es -> IO a) -> Eff es a
forall (es :: [Effect]) a. (Env es -> IO a) -> Eff es a
unsafeEff ((Env es -> IO a) -> Eff es a) -> (Env es -> IO a) -> Eff es a
forall a b. (a -> b) -> a -> b
$ \Env es
es -> do
Env es
-> Persistence
-> Limit
-> ((forall r. Eff es r -> IO r) -> IO a)
-> IO a
forall (es :: [Effect]) a.
HasCallStack =>
Env es
-> Persistence
-> Limit
-> ((forall r. Eff es r -> IO r) -> IO a)
-> IO a
concUnliftIO Env es
es Persistence
p Limit
l (((forall r. Eff es r -> IO r) -> IO a) -> IO a)
-> ((forall r. Eff es r -> IO r) -> IO a) -> IO a
forall a b. (a -> b) -> a -> b
$ \forall r. Eff es r -> IO r
unlift -> do
(Eff es a -> Env es -> IO a
forall (es :: [Effect]) a. Eff es a -> Env es -> IO a
`unEff` Env es
es) (Eff es a -> IO a) -> Eff es a -> IO a
forall a b. (a -> b) -> a -> b
$ (forall r. Eff es r -> Eff localEs r) -> Eff es a
k ((forall r. Eff es r -> Eff localEs r) -> Eff es a)
-> (forall r. Eff es r -> Eff localEs r) -> Eff es a
forall a b. (a -> b) -> a -> b
$ IO r -> Eff localEs r
forall a (es :: [Effect]). IO a -> Eff es a
unsafeEff_ (IO r -> Eff localEs r)
-> (Eff es r -> IO r) -> Eff es r -> Eff localEs r
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Eff es r -> IO r
forall r. Eff es r -> IO r
unlift
{-# INLINE localLift #-}
withLiftMap
:: (HasCallStack, SharedSuffix es handlerEs)
=> LocalEnv localEs handlerEs
-> ((forall a b. (Eff es a -> Eff es b) -> Eff localEs a -> Eff localEs b) -> Eff es r)
-> Eff es r
withLiftMap :: forall (es :: [Effect]) (handlerEs :: [Effect])
(localEs :: [Effect]) r.
(HasCallStack, SharedSuffix es handlerEs) =>
LocalEnv localEs handlerEs
-> ((forall a b.
(Eff es a -> Eff es b) -> Eff localEs a -> Eff localEs b)
-> Eff es r)
-> Eff es r
withLiftMap !LocalEnv localEs handlerEs
_ (forall a b.
(Eff es a -> Eff es b) -> Eff localEs a -> Eff localEs b)
-> Eff es r
k = (Env es -> IO r) -> Eff es r
forall (es :: [Effect]) a. (Env es -> IO a) -> Eff es a
unsafeEff ((Env es -> IO r) -> Eff es r) -> (Env es -> IO r) -> Eff es r
forall a b. (a -> b) -> a -> b
$ \Env es
es -> do
(Eff es r -> Env es -> IO r
forall (es :: [Effect]) a. Eff es a -> Env es -> IO a
`unEff` Env es
es) (Eff es r -> IO r) -> Eff es r -> IO r
forall a b. (a -> b) -> a -> b
$ (forall a b.
(Eff es a -> Eff es b) -> Eff localEs a -> Eff localEs b)
-> Eff es r
k ((forall a b.
(Eff es a -> Eff es b) -> Eff localEs a -> Eff localEs b)
-> Eff es r)
-> (forall a b.
(Eff es a -> Eff es b) -> Eff localEs a -> Eff localEs b)
-> Eff es r
forall a b. (a -> b) -> a -> b
$ \Eff es a -> Eff es b
mapEff Eff localEs a
m -> (Env localEs -> IO b) -> Eff localEs b
forall (es :: [Effect]) a. (Env es -> IO a) -> Eff es a
unsafeEff ((Env localEs -> IO b) -> Eff localEs b)
-> (Env localEs -> IO b) -> Eff localEs b
forall a b. (a -> b) -> a -> b
$ \Env localEs
localEs -> do
Env localEs -> ((forall r. Eff localEs r -> IO r) -> IO b) -> IO b
forall (es :: [Effect]) a.
HasCallStack =>
Env es -> ((forall r. Eff es r -> IO r) -> IO a) -> IO a
seqUnliftIO Env localEs
localEs (((forall r. Eff localEs r -> IO r) -> IO b) -> IO b)
-> ((forall r. Eff localEs r -> IO r) -> IO b) -> IO b
forall a b. (a -> b) -> a -> b
$ \forall r. Eff localEs r -> IO r
unlift -> do
(Eff es b -> Env es -> IO b
forall (es :: [Effect]) a. Eff es a -> Env es -> IO a
`unEff` Env es
es) (Eff es b -> IO b) -> (IO a -> Eff es b) -> IO a -> IO b
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Eff es a -> Eff es b
mapEff (Eff es a -> Eff es b) -> (IO a -> Eff es a) -> IO a -> Eff es b
forall b c a. (b -> c) -> (a -> b) -> a -> c
. IO a -> Eff es a
forall a (es :: [Effect]). IO a -> Eff es a
unsafeEff_ (IO a -> IO b) -> IO a -> IO b
forall a b. (a -> b) -> a -> b
$ Eff localEs a -> IO a
forall r. Eff localEs r -> IO r
unlift Eff localEs a
m
withLiftMapIO
:: (HasCallStack, SharedSuffix es handlerEs, IOE :> es)
=> LocalEnv localEs handlerEs
-> ((forall a b. (IO a -> IO b) -> Eff localEs a -> Eff localEs b) -> Eff es r)
-> Eff es r
withLiftMapIO :: forall (es :: [Effect]) (handlerEs :: [Effect])
(localEs :: [Effect]) r.
(HasCallStack, SharedSuffix es handlerEs, IOE :> es) =>
LocalEnv localEs handlerEs
-> ((forall a b. (IO a -> IO b) -> Eff localEs a -> Eff localEs b)
-> Eff es r)
-> Eff es r
withLiftMapIO !LocalEnv localEs handlerEs
_ (forall a b. (IO a -> IO b) -> Eff localEs a -> Eff localEs b)
-> Eff es r
k = (forall a b. (IO a -> IO b) -> Eff localEs a -> Eff localEs b)
-> Eff es r
k ((forall a b. (IO a -> IO b) -> Eff localEs a -> Eff localEs b)
-> Eff es r)
-> (forall a b. (IO a -> IO b) -> Eff localEs a -> Eff localEs b)
-> Eff es r
forall a b. (a -> b) -> a -> b
$ \IO a -> IO b
mapIO Eff localEs a
m -> (Env localEs -> IO b) -> Eff localEs b
forall (es :: [Effect]) a. (Env es -> IO a) -> Eff es a
unsafeEff ((Env localEs -> IO b) -> Eff localEs b)
-> (Env localEs -> IO b) -> Eff localEs b
forall a b. (a -> b) -> a -> b
$ \Env localEs
es -> do
Env localEs -> ((forall r. Eff localEs r -> IO r) -> IO b) -> IO b
forall (es :: [Effect]) a.
HasCallStack =>
Env es -> ((forall r. Eff es r -> IO r) -> IO a) -> IO a
seqUnliftIO Env localEs
es (((forall r. Eff localEs r -> IO r) -> IO b) -> IO b)
-> ((forall r. Eff localEs r -> IO r) -> IO b) -> IO b
forall a b. (a -> b) -> a -> b
$ \forall r. Eff localEs r -> IO r
unlift -> IO a -> IO b
mapIO (IO a -> IO b) -> IO a -> IO b
forall a b. (a -> b) -> a -> b
$ Eff localEs a -> IO a
forall r. Eff localEs r -> IO r
unlift Eff localEs a
m
localLiftUnlift
:: (HasCallStack, SharedSuffix es handlerEs)
=> LocalEnv localEs handlerEs
-> UnliftStrategy
-> ((forall r. Eff es r -> Eff localEs r) -> (forall r. Eff localEs r -> Eff es r) -> Eff es a)
-> Eff es a
localLiftUnlift :: forall (es :: [Effect]) (handlerEs :: [Effect])
(localEs :: [Effect]) a.
(HasCallStack, SharedSuffix es handlerEs) =>
LocalEnv localEs handlerEs
-> UnliftStrategy
-> ((forall r. Eff es r -> Eff localEs r)
-> (forall r. Eff localEs r -> Eff es r) -> Eff es a)
-> Eff es a
localLiftUnlift (LocalEnv Env localEs
les) UnliftStrategy
strategy (forall r. Eff es r -> Eff localEs r)
-> (forall r. Eff localEs r -> Eff es r) -> Eff es a
k = case UnliftStrategy
strategy of
UnliftStrategy
SeqUnlift -> (Env es -> IO a) -> Eff es a
forall (es :: [Effect]) a. (Env es -> IO a) -> Eff es a
unsafeEff ((Env es -> IO a) -> Eff es a) -> (Env es -> IO a) -> Eff es a
forall a b. (a -> b) -> a -> b
$ \Env es
es -> do
Env es -> ((forall r. Eff es r -> IO r) -> IO a) -> IO a
forall (es :: [Effect]) a.
HasCallStack =>
Env es -> ((forall r. Eff es r -> IO r) -> IO a) -> IO a
seqUnliftIO Env es
es (((forall r. Eff es r -> IO r) -> IO a) -> IO a)
-> ((forall r. Eff es r -> IO r) -> IO a) -> IO a
forall a b. (a -> b) -> a -> b
$ \forall r. Eff es r -> IO r
unliftEs -> do
Env localEs -> ((forall r. Eff localEs r -> IO r) -> IO a) -> IO a
forall (es :: [Effect]) a.
HasCallStack =>
Env es -> ((forall r. Eff es r -> IO r) -> IO a) -> IO a
seqUnliftIO Env localEs
les (((forall r. Eff localEs r -> IO r) -> IO a) -> IO a)
-> ((forall r. Eff localEs r -> IO r) -> IO a) -> IO a
forall a b. (a -> b) -> a -> b
$ \forall r. Eff localEs r -> IO r
unliftLocalEs -> do
(Eff es a -> Env es -> IO a
forall (es :: [Effect]) a. Eff es a -> Env es -> IO a
`unEff` Env es
es) (Eff es a -> IO a) -> Eff es a -> IO a
forall a b. (a -> b) -> a -> b
$ (forall r. Eff es r -> Eff localEs r)
-> (forall r. Eff localEs r -> Eff es r) -> Eff es a
k (IO r -> Eff localEs r
forall a (es :: [Effect]). IO a -> Eff es a
unsafeEff_ (IO r -> Eff localEs r)
-> (Eff es r -> IO r) -> Eff es r -> Eff localEs r
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Eff es r -> IO r
forall r. Eff es r -> IO r
unliftEs) (IO r -> Eff es r
forall a (es :: [Effect]). IO a -> Eff es a
unsafeEff_ (IO r -> Eff es r)
-> (Eff localEs r -> IO r) -> Eff localEs r -> Eff es r
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Eff localEs r -> IO r
forall r. Eff localEs r -> IO r
unliftLocalEs)
ConcUnlift Persistence
p Limit
l -> (Env es -> IO a) -> Eff es a
forall (es :: [Effect]) a. (Env es -> IO a) -> Eff es a
unsafeEff ((Env es -> IO a) -> Eff es a) -> (Env es -> IO a) -> Eff es a
forall a b. (a -> b) -> a -> b
$ \Env es
es -> do
Env es
-> Persistence
-> Limit
-> ((forall r. Eff es r -> IO r) -> IO a)
-> IO a
forall (es :: [Effect]) a.
HasCallStack =>
Env es
-> Persistence
-> Limit
-> ((forall r. Eff es r -> IO r) -> IO a)
-> IO a
concUnliftIO Env es
es Persistence
p Limit
l (((forall r. Eff es r -> IO r) -> IO a) -> IO a)
-> ((forall r. Eff es r -> IO r) -> IO a) -> IO a
forall a b. (a -> b) -> a -> b
$ \forall r. Eff es r -> IO r
unliftEs -> do
Env localEs
-> Persistence
-> Limit
-> ((forall r. Eff localEs r -> IO r) -> IO a)
-> IO a
forall (es :: [Effect]) a.
HasCallStack =>
Env es
-> Persistence
-> Limit
-> ((forall r. Eff es r -> IO r) -> IO a)
-> IO a
concUnliftIO Env localEs
les Persistence
p Limit
l (((forall r. Eff localEs r -> IO r) -> IO a) -> IO a)
-> ((forall r. Eff localEs r -> IO r) -> IO a) -> IO a
forall a b. (a -> b) -> a -> b
$ \forall r. Eff localEs r -> IO r
unliftLocalEs -> do
(Eff es a -> Env es -> IO a
forall (es :: [Effect]) a. Eff es a -> Env es -> IO a
`unEff` Env es
es) (Eff es a -> IO a) -> Eff es a -> IO a
forall a b. (a -> b) -> a -> b
$ (forall r. Eff es r -> Eff localEs r)
-> (forall r. Eff localEs r -> Eff es r) -> Eff es a
k (IO r -> Eff localEs r
forall a (es :: [Effect]). IO a -> Eff es a
unsafeEff_ (IO r -> Eff localEs r)
-> (Eff es r -> IO r) -> Eff es r -> Eff localEs r
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Eff es r -> IO r
forall r. Eff es r -> IO r
unliftEs) (IO r -> Eff es r
forall a (es :: [Effect]). IO a -> Eff es a
unsafeEff_ (IO r -> Eff es r)
-> (Eff localEs r -> IO r) -> Eff localEs r -> Eff es r
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Eff localEs r -> IO r
forall r. Eff localEs r -> IO r
unliftLocalEs)
{-# INLINE localLiftUnlift #-}
localLiftUnliftIO
:: (HasCallStack, SharedSuffix es handlerEs, IOE :> es)
=> LocalEnv localEs handlerEs
-> UnliftStrategy
-> ((forall r. IO r -> Eff localEs r) -> (forall r. Eff localEs r -> IO r) -> IO a)
-> Eff es a
localLiftUnliftIO :: forall (es :: [Effect]) (handlerEs :: [Effect])
(localEs :: [Effect]) a.
(HasCallStack, SharedSuffix es handlerEs, IOE :> es) =>
LocalEnv localEs handlerEs
-> UnliftStrategy
-> ((forall r. IO r -> Eff localEs r)
-> (forall r. Eff localEs r -> IO r) -> IO a)
-> Eff es a
localLiftUnliftIO (LocalEnv Env localEs
les) UnliftStrategy
strategy (forall r. IO r -> Eff localEs r)
-> (forall r. Eff localEs r -> IO r) -> IO a
k = case UnliftStrategy
strategy of
UnliftStrategy
SeqUnlift -> IO a -> Eff es a
forall a. IO a -> Eff es a
forall (m :: Type -> Type) a. MonadIO m => IO a -> m a
liftIO (IO a -> Eff es a) -> IO a -> Eff es a
forall a b. (a -> b) -> a -> b
$ Env localEs -> ((forall r. Eff localEs r -> IO r) -> IO a) -> IO a
forall (es :: [Effect]) a.
HasCallStack =>
Env es -> ((forall r. Eff es r -> IO r) -> IO a) -> IO a
seqUnliftIO Env localEs
les (((forall r. Eff localEs r -> IO r) -> IO a) -> IO a)
-> ((forall r. Eff localEs r -> IO r) -> IO a) -> IO a
forall a b. (a -> b) -> a -> b
$ (forall r. IO r -> Eff localEs r)
-> (forall r. Eff localEs r -> IO r) -> IO a
k IO r -> Eff localEs r
forall r. IO r -> Eff localEs r
forall a (es :: [Effect]). IO a -> Eff es a
unsafeEff_
ConcUnlift Persistence
p Limit
l -> IO a -> Eff es a
forall a. IO a -> Eff es a
forall (m :: Type -> Type) a. MonadIO m => IO a -> m a
liftIO (IO a -> Eff es a) -> IO a -> Eff es a
forall a b. (a -> b) -> a -> b
$ Env localEs
-> Persistence
-> Limit
-> ((forall r. Eff localEs r -> IO r) -> IO a)
-> IO a
forall (es :: [Effect]) a.
HasCallStack =>
Env es
-> Persistence
-> Limit
-> ((forall r. Eff es r -> IO r) -> IO a)
-> IO a
concUnliftIO Env localEs
les Persistence
p Limit
l (((forall r. Eff localEs r -> IO r) -> IO a) -> IO a)
-> ((forall r. Eff localEs r -> IO r) -> IO a) -> IO a
forall a b. (a -> b) -> a -> b
$ (forall r. IO r -> Eff localEs r)
-> (forall r. Eff localEs r -> IO r) -> IO a
k IO r -> Eff localEs r
forall r. IO r -> Eff localEs r
forall a (es :: [Effect]). IO a -> Eff es a
unsafeEff_
{-# INLINE localLiftUnliftIO #-}
localSeqLend
:: (e :> es, SharedSuffix es handlerEs)
=> LocalEnv localEs handlerEs
-> ((forall r. Eff (e : localEs) r -> Eff localEs r) -> Eff es a)
-> Eff es a
localSeqLend :: forall (e :: Effect) (es :: [Effect]) (handlerEs :: [Effect])
(localEs :: [Effect]) a.
(e :> es, SharedSuffix es handlerEs) =>
LocalEnv localEs handlerEs
-> ((forall r. Eff (e : localEs) r -> Eff localEs r) -> Eff es a)
-> Eff es a
localSeqLend (LocalEnv Env localEs
les) (forall r. Eff (e : localEs) r -> Eff localEs r) -> Eff es a
k = (Env es -> IO a) -> Eff es a
forall (es :: [Effect]) a. (Env es -> IO a) -> Eff es a
unsafeEff ((Env es -> IO a) -> Eff es a) -> (Env es -> IO a) -> Eff es a
forall a b. (a -> b) -> a -> b
$ \Env es
es -> do
Env (e : localEs)
eles <- Env es -> Env localEs -> IO (Env (e : localEs))
forall (e :: Effect) (srcEs :: [Effect]) (destEs :: [Effect]).
(e :> srcEs) =>
Env srcEs -> Env destEs -> IO (Env (e : destEs))
copyRef Env es
es Env localEs
les
Env (e : localEs)
-> ((forall r. Eff (e : localEs) r -> IO r) -> IO a) -> IO a
forall (es :: [Effect]) a.
HasCallStack =>
Env es -> ((forall r. Eff es r -> IO r) -> IO a) -> IO a
seqUnliftIO Env (e : localEs)
eles (((forall r. Eff (e : localEs) r -> IO r) -> IO a) -> IO a)
-> ((forall r. Eff (e : localEs) r -> IO r) -> IO a) -> IO a
forall a b. (a -> b) -> a -> b
$ \forall r. Eff (e : localEs) r -> IO r
unlift -> (Eff es a -> Env es -> IO a
forall (es :: [Effect]) a. Eff es a -> Env es -> IO a
`unEff` Env es
es) (Eff es a -> IO a) -> Eff es a -> IO a
forall a b. (a -> b) -> a -> b
$ (forall r. Eff (e : localEs) r -> Eff localEs r) -> Eff es a
k ((forall r. Eff (e : localEs) r -> Eff localEs r) -> Eff es a)
-> (forall r. Eff (e : localEs) r -> Eff localEs r) -> Eff es a
forall a b. (a -> b) -> a -> b
$ IO r -> Eff localEs r
forall a (es :: [Effect]). IO a -> Eff es a
unsafeEff_ (IO r -> Eff localEs r)
-> (Eff (e : localEs) r -> IO r)
-> Eff (e : localEs) r
-> Eff localEs r
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Eff (e : localEs) r -> IO r
forall r. Eff (e : localEs) r -> IO r
unlift
localLend
:: (e :> es, SharedSuffix es handlerEs)
=> LocalEnv localEs handlerEs
-> UnliftStrategy
-> ((forall r. Eff (e : localEs) r -> Eff localEs r) -> Eff es a)
-> Eff es a
localLend :: forall (e :: Effect) (es :: [Effect]) (handlerEs :: [Effect])
(localEs :: [Effect]) a.
(e :> es, SharedSuffix es handlerEs) =>
LocalEnv localEs handlerEs
-> UnliftStrategy
-> ((forall r. Eff (e : localEs) r -> Eff localEs r) -> Eff es a)
-> Eff es a
localLend (LocalEnv Env localEs
les) UnliftStrategy
strategy (forall r. Eff (e : localEs) r -> Eff localEs r) -> Eff es a
k = case UnliftStrategy
strategy of
UnliftStrategy
SeqUnlift -> (Env es -> IO a) -> Eff es a
forall (es :: [Effect]) a. (Env es -> IO a) -> Eff es a
unsafeEff ((Env es -> IO a) -> Eff es a) -> (Env es -> IO a) -> Eff es a
forall a b. (a -> b) -> a -> b
$ \Env es
es -> do
Env (e : localEs)
eles <- Env es -> Env localEs -> IO (Env (e : localEs))
forall (e :: Effect) (srcEs :: [Effect]) (destEs :: [Effect]).
(e :> srcEs) =>
Env srcEs -> Env destEs -> IO (Env (e : destEs))
copyRef Env es
es Env localEs
les
Env (e : localEs)
-> ((forall r. Eff (e : localEs) r -> IO r) -> IO a) -> IO a
forall (es :: [Effect]) a.
HasCallStack =>
Env es -> ((forall r. Eff es r -> IO r) -> IO a) -> IO a
seqUnliftIO Env (e : localEs)
eles (((forall r. Eff (e : localEs) r -> IO r) -> IO a) -> IO a)
-> ((forall r. Eff (e : localEs) r -> IO r) -> IO a) -> IO a
forall a b. (a -> b) -> a -> b
$ \forall r. Eff (e : localEs) r -> IO r
unlift -> (Eff es a -> Env es -> IO a
forall (es :: [Effect]) a. Eff es a -> Env es -> IO a
`unEff` Env es
es) (Eff es a -> IO a) -> Eff es a -> IO a
forall a b. (a -> b) -> a -> b
$ (forall r. Eff (e : localEs) r -> Eff localEs r) -> Eff es a
k ((forall r. Eff (e : localEs) r -> Eff localEs r) -> Eff es a)
-> (forall r. Eff (e : localEs) r -> Eff localEs r) -> Eff es a
forall a b. (a -> b) -> a -> b
$ IO r -> Eff localEs r
forall a (es :: [Effect]). IO a -> Eff es a
unsafeEff_ (IO r -> Eff localEs r)
-> (Eff (e : localEs) r -> IO r)
-> Eff (e : localEs) r
-> Eff localEs r
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Eff (e : localEs) r -> IO r
forall r. Eff (e : localEs) r -> IO r
unlift
ConcUnlift Persistence
p Limit
l -> (Env es -> IO a) -> Eff es a
forall (es :: [Effect]) a. (Env es -> IO a) -> Eff es a
unsafeEff ((Env es -> IO a) -> Eff es a) -> (Env es -> IO a) -> Eff es a
forall a b. (a -> b) -> a -> b
$ \Env es
es -> do
Env (e : localEs)
eles <- Env es -> Env localEs -> IO (Env (e : localEs))
forall (e :: Effect) (srcEs :: [Effect]) (destEs :: [Effect]).
(e :> srcEs) =>
Env srcEs -> Env destEs -> IO (Env (e : destEs))
copyRef Env es
es Env localEs
les
Env (e : localEs)
-> Persistence
-> Limit
-> ((forall r. Eff (e : localEs) r -> IO r) -> IO a)
-> IO a
forall (es :: [Effect]) a.
HasCallStack =>
Env es
-> Persistence
-> Limit
-> ((forall r. Eff es r -> IO r) -> IO a)
-> IO a
concUnliftIO Env (e : localEs)
eles Persistence
p Limit
l (((forall r. Eff (e : localEs) r -> IO r) -> IO a) -> IO a)
-> ((forall r. Eff (e : localEs) r -> IO r) -> IO a) -> IO a
forall a b. (a -> b) -> a -> b
$ \forall r. Eff (e : localEs) r -> IO r
unlift -> (Eff es a -> Env es -> IO a
forall (es :: [Effect]) a. Eff es a -> Env es -> IO a
`unEff` Env es
es) (Eff es a -> IO a) -> Eff es a -> IO a
forall a b. (a -> b) -> a -> b
$ (forall r. Eff (e : localEs) r -> Eff localEs r) -> Eff es a
k ((forall r. Eff (e : localEs) r -> Eff localEs r) -> Eff es a)
-> (forall r. Eff (e : localEs) r -> Eff localEs r) -> Eff es a
forall a b. (a -> b) -> a -> b
$ IO r -> Eff localEs r
forall a (es :: [Effect]). IO a -> Eff es a
unsafeEff_ (IO r -> Eff localEs r)
-> (Eff (e : localEs) r -> IO r)
-> Eff (e : localEs) r
-> Eff localEs r
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Eff (e : localEs) r -> IO r
forall r. Eff (e : localEs) r -> IO r
unlift
{-# INLINE localLend #-}
localSeqBorrow
:: (e :> localEs, SharedSuffix es handlerEs)
=> LocalEnv localEs handlerEs
-> ((forall r. Eff (e : es) r -> Eff es r) -> Eff es a)
-> Eff es a
localSeqBorrow :: forall (e :: Effect) (localEs :: [Effect]) (es :: [Effect])
(handlerEs :: [Effect]) a.
(e :> localEs, SharedSuffix es handlerEs) =>
LocalEnv localEs handlerEs
-> ((forall r. Eff (e : es) r -> Eff es r) -> Eff es a) -> Eff es a
localSeqBorrow (LocalEnv Env localEs
les) (forall r. Eff (e : es) r -> Eff es r) -> Eff es a
k = (Env es -> IO a) -> Eff es a
forall (es :: [Effect]) a. (Env es -> IO a) -> Eff es a
unsafeEff ((Env es -> IO a) -> Eff es a) -> (Env es -> IO a) -> Eff es a
forall a b. (a -> b) -> a -> b
$ \Env es
es -> do
Env (e : es)
ees <- Env localEs -> Env es -> IO (Env (e : es))
forall (e :: Effect) (srcEs :: [Effect]) (destEs :: [Effect]).
(e :> srcEs) =>
Env srcEs -> Env destEs -> IO (Env (e : destEs))
copyRef Env localEs
les Env es
es
Env (e : es)
-> ((forall r. Eff (e : es) r -> IO r) -> IO a) -> IO a
forall (es :: [Effect]) a.
HasCallStack =>
Env es -> ((forall r. Eff es r -> IO r) -> IO a) -> IO a
seqUnliftIO Env (e : es)
ees (((forall r. Eff (e : es) r -> IO r) -> IO a) -> IO a)
-> ((forall r. Eff (e : es) r -> IO r) -> IO a) -> IO a
forall a b. (a -> b) -> a -> b
$ \forall r. Eff (e : es) r -> IO r
unlift -> (Eff es a -> Env es -> IO a
forall (es :: [Effect]) a. Eff es a -> Env es -> IO a
`unEff` Env es
es) (Eff es a -> IO a) -> Eff es a -> IO a
forall a b. (a -> b) -> a -> b
$ (forall r. Eff (e : es) r -> Eff es r) -> Eff es a
k ((forall r. Eff (e : es) r -> Eff es r) -> Eff es a)
-> (forall r. Eff (e : es) r -> Eff es r) -> Eff es a
forall a b. (a -> b) -> a -> b
$ IO r -> Eff es r
forall a (es :: [Effect]). IO a -> Eff es a
unsafeEff_ (IO r -> Eff es r)
-> (Eff (e : es) r -> IO r) -> Eff (e : es) r -> Eff es r
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Eff (e : es) r -> IO r
forall r. Eff (e : es) r -> IO r
unlift
localBorrow
:: (e :> localEs, SharedSuffix es handlerEs)
=> LocalEnv localEs handlerEs
-> UnliftStrategy
-> ((forall r. Eff (e : es) r -> Eff es r) -> Eff es a)
-> Eff es a
localBorrow :: forall (e :: Effect) (localEs :: [Effect]) (es :: [Effect])
(handlerEs :: [Effect]) a.
(e :> localEs, SharedSuffix es handlerEs) =>
LocalEnv localEs handlerEs
-> UnliftStrategy
-> ((forall r. Eff (e : es) r -> Eff es r) -> Eff es a)
-> Eff es a
localBorrow (LocalEnv Env localEs
les) UnliftStrategy
strategy (forall r. Eff (e : es) r -> Eff es r) -> Eff es a
k = case UnliftStrategy
strategy of
UnliftStrategy
SeqUnlift -> (Env es -> IO a) -> Eff es a
forall (es :: [Effect]) a. (Env es -> IO a) -> Eff es a
unsafeEff ((Env es -> IO a) -> Eff es a) -> (Env es -> IO a) -> Eff es a
forall a b. (a -> b) -> a -> b
$ \Env es
es -> do
Env (e : es)
ees <- Env localEs -> Env es -> IO (Env (e : es))
forall (e :: Effect) (srcEs :: [Effect]) (destEs :: [Effect]).
(e :> srcEs) =>
Env srcEs -> Env destEs -> IO (Env (e : destEs))
copyRef Env localEs
les Env es
es
Env (e : es)
-> ((forall r. Eff (e : es) r -> IO r) -> IO a) -> IO a
forall (es :: [Effect]) a.
HasCallStack =>
Env es -> ((forall r. Eff es r -> IO r) -> IO a) -> IO a
seqUnliftIO Env (e : es)
ees (((forall r. Eff (e : es) r -> IO r) -> IO a) -> IO a)
-> ((forall r. Eff (e : es) r -> IO r) -> IO a) -> IO a
forall a b. (a -> b) -> a -> b
$ \forall r. Eff (e : es) r -> IO r
unlift -> (Eff es a -> Env es -> IO a
forall (es :: [Effect]) a. Eff es a -> Env es -> IO a
`unEff` Env es
es) (Eff es a -> IO a) -> Eff es a -> IO a
forall a b. (a -> b) -> a -> b
$ (forall r. Eff (e : es) r -> Eff es r) -> Eff es a
k ((forall r. Eff (e : es) r -> Eff es r) -> Eff es a)
-> (forall r. Eff (e : es) r -> Eff es r) -> Eff es a
forall a b. (a -> b) -> a -> b
$ IO r -> Eff es r
forall a (es :: [Effect]). IO a -> Eff es a
unsafeEff_ (IO r -> Eff es r)
-> (Eff (e : es) r -> IO r) -> Eff (e : es) r -> Eff es r
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Eff (e : es) r -> IO r
forall r. Eff (e : es) r -> IO r
unlift
ConcUnlift Persistence
p Limit
l -> (Env es -> IO a) -> Eff es a
forall (es :: [Effect]) a. (Env es -> IO a) -> Eff es a
unsafeEff ((Env es -> IO a) -> Eff es a) -> (Env es -> IO a) -> Eff es a
forall a b. (a -> b) -> a -> b
$ \Env es
es -> do
Env (e : es)
ees <- Env localEs -> Env es -> IO (Env (e : es))
forall (e :: Effect) (srcEs :: [Effect]) (destEs :: [Effect]).
(e :> srcEs) =>
Env srcEs -> Env destEs -> IO (Env (e : destEs))
copyRef Env localEs
les Env es
es
Env (e : es)
-> Persistence
-> Limit
-> ((forall r. Eff (e : es) r -> IO r) -> IO a)
-> IO a
forall (es :: [Effect]) a.
HasCallStack =>
Env es
-> Persistence
-> Limit
-> ((forall r. Eff es r -> IO r) -> IO a)
-> IO a
concUnliftIO Env (e : es)
ees Persistence
p Limit
l (((forall r. Eff (e : es) r -> IO r) -> IO a) -> IO a)
-> ((forall r. Eff (e : es) r -> IO r) -> IO a) -> IO a
forall a b. (a -> b) -> a -> b
$ \forall r. Eff (e : es) r -> IO r
unlift -> (Eff es a -> Env es -> IO a
forall (es :: [Effect]) a. Eff es a -> Env es -> IO a
`unEff` Env es
es) (Eff es a -> IO a) -> Eff es a -> IO a
forall a b. (a -> b) -> a -> b
$ (forall r. Eff (e : es) r -> Eff es r) -> Eff es a
k ((forall r. Eff (e : es) r -> Eff es r) -> Eff es a)
-> (forall r. Eff (e : es) r -> Eff es r) -> Eff es a
forall a b. (a -> b) -> a -> b
$ IO r -> Eff es r
forall a (es :: [Effect]). IO a -> Eff es a
unsafeEff_ (IO r -> Eff es r)
-> (Eff (e : es) r -> IO r) -> Eff (e : es) r -> Eff es r
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Eff (e : es) r -> IO r
forall r. Eff (e : es) r -> IO r
unlift
{-# INLINE localBorrow #-}
copyRef
:: forall e srcEs destEs. e :> srcEs
=> Env srcEs
-> Env destEs
-> IO (Env (e : destEs))
copyRef :: forall (e :: Effect) (srcEs :: [Effect]) (destEs :: [Effect]).
(e :> srcEs) =>
Env srcEs -> Env destEs -> IO (Env (e : destEs))
copyRef (Env Int
hoffset PrimArray Int
hrefs IORef' Storage
hstorage) (Env Int
offset PrimArray Int
refs0 IORef' Storage
storage) = do
Bool -> IO () -> IO ()
forall (f :: Type -> Type). Applicative f => Bool -> f () -> f ()
when (IORef' Storage
hstorage IORef' Storage -> IORef' Storage -> Bool
forall a. Eq a => a -> a -> Bool
/= IORef' Storage
storage) (IO () -> IO ()) -> IO () -> IO ()
forall a b. (a -> b) -> a -> b
$ do
[Char] -> IO ()
forall a. HasCallStack => [Char] -> a
error [Char]
"storages do not match"
let size :: Int
size = PrimArray Int -> Int
forall a. Prim a => PrimArray a -> Int
sizeofPrimArray PrimArray Int
refs0 Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
offset
i :: Int
i = Int
2 Int -> Int -> Int
forall a. Num a => a -> a -> a
* forall (e :: Effect) (es :: [Effect]). (e :> es) => Int
reifyIndex @e @srcEs
MutablePrimArray RealWorld Int
mrefs <- Int -> IO (MutablePrimArray (PrimState IO) Int)
forall (m :: Type -> Type) a.
(PrimMonad m, Prim a) =>
Int -> m (MutablePrimArray (PrimState m) a)
newPrimArray (Int
size Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
2)
MutablePrimArray (PrimState IO) Int
-> Int -> PrimArray Int -> Int -> Int -> IO ()
forall (m :: Type -> Type) a.
(PrimMonad m, Prim a) =>
MutablePrimArray (PrimState m) a
-> Int -> PrimArray a -> Int -> Int -> m ()
copyPrimArray MutablePrimArray RealWorld Int
MutablePrimArray (PrimState IO) Int
mrefs Int
0 PrimArray Int
hrefs (Int
hoffset Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
i) Int
2
MutablePrimArray (PrimState IO) Int
-> Int -> PrimArray Int -> Int -> Int -> IO ()
forall (m :: Type -> Type) a.
(PrimMonad m, Prim a) =>
MutablePrimArray (PrimState m) a
-> Int -> PrimArray a -> Int -> Int -> m ()
copyPrimArray MutablePrimArray RealWorld Int
MutablePrimArray (PrimState IO) Int
mrefs Int
2 PrimArray Int
refs0 Int
offset Int
size
PrimArray Int
refs <- MutablePrimArray (PrimState IO) Int -> IO (PrimArray Int)
forall (m :: Type -> Type) a.
PrimMonad m =>
MutablePrimArray (PrimState m) a -> m (PrimArray a)
unsafeFreezePrimArray MutablePrimArray RealWorld Int
MutablePrimArray (PrimState IO) Int
mrefs
Env (e : destEs) -> IO (Env (e : destEs))
forall a. a -> IO a
forall (f :: Type -> Type) a. Applicative f => a -> f a
pure (Env (e : destEs) -> IO (Env (e : destEs)))
-> Env (e : destEs) -> IO (Env (e : destEs))
forall a b. (a -> b) -> a -> b
$ Int -> PrimArray Int -> IORef' Storage -> Env (e : destEs)
forall (es :: [Effect]).
Int -> PrimArray Int -> IORef' Storage -> Env es
Env Int
0 PrimArray Int
refs IORef' Storage
storage
class SharedSuffix (es1 :: [Effect]) (es2 :: [Effect])
instance {-# INCOHERENT #-} SharedSuffix es es
instance {-# INCOHERENT #-} SharedSuffix es1 es2 => SharedSuffix (e : es1) es2
instance {-# INCOHERENT #-} SharedSuffix es1 es2 => SharedSuffix es1 (e : es2)
instance
TypeError
( Text "Running local actions in monomorphic effect stacks is not supported." :$$:
Text "As a solution simply change the stack to have a polymorphic suffix."
) => SharedSuffix '[] '[]