{-# LANGUAGE UndecidableInstances #-}
{-# OPTIONS_GHC -Wno-noncanonical-monad-instances #-}
{-# OPTIONS_GHC -Wno-orphans #-}
{-# OPTIONS_HADDOCK not-home #-}
module Effectful.Internal.Monad
(
Eff
, runPureEff
, unEff
, unsafeEff
, unsafeEff_
, NonDet(..)
, Fail(..)
, IOE
, runEff
, Prim
, PrimStateEff
, runPrim
, raise
, raiseWith
, subsume
, inject
, Subset
, UnliftStrategy(..)
, Persistence(..)
, Limit(..)
, unliftStrategy
, withUnliftStrategy
, withSeqEffToIO
, withEffToIO
, withConcEffToIO
, seqUnliftIO
, seqForkUnliftIO
, concUnliftIO
, EffectHandler
, LocalEnv(..)
, Handler(..)
, relinkHandler
, runHandler
, send
, StaticRep
, MaybeIOE
, runStaticRep
, evalStaticRep
, execStaticRep
, getStaticRep
, putStaticRep
, stateStaticRep
, stateStaticRepM
, localStaticRep
) where
import Control.Applicative
import Control.Concurrent (myThreadId)
import Control.Exception qualified as E
import Control.Monad
import Control.Monad.Base
import Control.Monad.Catch qualified as C
import Control.Monad.Fix
import Control.Monad.IO.Class
import Control.Monad.IO.Unlift
import Control.Monad.Primitive
import Control.Monad.Trans.Control
import Data.Kind (Constraint)
import GHC.Exts (oneShot)
import GHC.IO (IO(..))
import GHC.Stack
import System.IO.Unsafe (unsafeDupablePerformIO)
import Unsafe.Coerce (unsafeCoerce)
import Effectful.Internal.Effect
import Effectful.Internal.Env
import Effectful.Internal.Unlift
import Effectful.Internal.Utils
type role Eff nominal representational
newtype Eff (es :: [Effect]) a = Eff (Env es -> IO a)
deriving newtype (Semigroup (Eff es a)
Eff es a
Semigroup (Eff es a) =>
Eff es a
-> (Eff es a -> Eff es a -> Eff es a)
-> ([Eff es a] -> Eff es a)
-> Monoid (Eff es a)
[Eff es a] -> Eff es a
Eff es a -> Eff es a -> Eff es a
forall (es :: [Effect]) a. Monoid a => Semigroup (Eff es a)
forall (es :: [Effect]) a. Monoid a => Eff es a
forall (es :: [Effect]) a. Monoid a => [Eff es a] -> Eff es a
forall (es :: [Effect]) a.
Monoid a =>
Eff es a -> Eff es a -> Eff es a
forall a.
Semigroup a =>
a -> (a -> a -> a) -> ([a] -> a) -> Monoid a
$cmempty :: forall (es :: [Effect]) a. Monoid a => Eff es a
mempty :: Eff es a
$cmappend :: forall (es :: [Effect]) a.
Monoid a =>
Eff es a -> Eff es a -> Eff es a
mappend :: Eff es a -> Eff es a -> Eff es a
$cmconcat :: forall (es :: [Effect]) a. Monoid a => [Eff es a] -> Eff es a
mconcat :: [Eff es a] -> Eff es a
Monoid, NonEmpty (Eff es a) -> Eff es a
Eff es a -> Eff es a -> Eff es a
(Eff es a -> Eff es a -> Eff es a)
-> (NonEmpty (Eff es a) -> Eff es a)
-> (forall b. Integral b => b -> Eff es a -> Eff es a)
-> Semigroup (Eff es a)
forall (es :: [Effect]) a.
Semigroup a =>
NonEmpty (Eff es a) -> Eff es a
forall (es :: [Effect]) a.
Semigroup a =>
Eff es a -> Eff es a -> Eff es a
forall (es :: [Effect]) a b.
(Semigroup a, Integral b) =>
b -> Eff es a -> Eff es a
forall b. Integral b => b -> Eff es a -> Eff es a
forall a.
(a -> a -> a)
-> (NonEmpty a -> a)
-> (forall b. Integral b => b -> a -> a)
-> Semigroup a
$c<> :: forall (es :: [Effect]) a.
Semigroup a =>
Eff es a -> Eff es a -> Eff es a
<> :: Eff es a -> Eff es a -> Eff es a
$csconcat :: forall (es :: [Effect]) a.
Semigroup a =>
NonEmpty (Eff es a) -> Eff es a
sconcat :: NonEmpty (Eff es a) -> Eff es a
$cstimes :: forall (es :: [Effect]) a b.
(Semigroup a, Integral b) =>
b -> Eff es a -> Eff es a
stimes :: forall b. Integral b => b -> Eff es a -> Eff es a
Semigroup)
runPureEff :: HasCallStack => Eff '[] a -> a
runPureEff :: forall a. HasCallStack => Eff '[] a -> a
runPureEff (Eff Env '[] -> IO a
m) =
IO a -> a
forall a. IO a -> a
unsafeDupablePerformIO (IO a -> a) -> IO a -> a
forall a b. (a -> b) -> a -> b
$ Env '[] -> IO a
m (Env '[] -> IO a) -> IO (Env '[]) -> IO a
forall (m :: Type -> Type) a b. Monad m => (a -> m b) -> m a -> m b
=<< IO (Env '[])
HasCallStack => IO (Env '[])
emptyEnv
unEff :: Eff es a -> Env es -> IO a
unEff :: forall (es :: [Effect]) a. Eff es a -> Env es -> IO a
unEff (Eff Env es -> IO a
m) = Env es -> IO a
m
unsafeEff :: (Env es -> IO a) -> Eff es a
unsafeEff :: forall (es :: [Effect]) a. (Env es -> IO a) -> Eff es a
unsafeEff Env es -> IO a
m = (Env es -> IO a) -> Eff es a
forall (es :: [Effect]) a. (Env es -> IO a) -> Eff es a
Eff ((Env es -> IO a) -> Env es -> IO a
forall a b. (a -> b) -> a -> b
oneShot Env es -> IO a
m)
unsafeEff_ :: IO a -> Eff es a
unsafeEff_ :: forall a (es :: [Effect]). IO a -> Eff es a
unsafeEff_ IO 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
_ -> IO a
m
unliftStrategy :: IOE :> es => Eff es UnliftStrategy
unliftStrategy :: forall (es :: [Effect]). (IOE :> es) => Eff es UnliftStrategy
unliftStrategy = do
IOE UnliftStrategy
unlift <- Eff es (StaticRep IOE)
forall (e :: Effect) (sideEffects :: SideEffects) (es :: [Effect]).
(HasCallStack, DispatchOf e ~ 'Static sideEffects, e :> es) =>
Eff es (StaticRep e)
getStaticRep
UnliftStrategy -> Eff es UnliftStrategy
forall a. a -> Eff es a
forall (f :: Type -> Type) a. Applicative f => a -> f a
pure UnliftStrategy
unlift
withUnliftStrategy :: IOE :> es => UnliftStrategy -> Eff es a -> Eff es a
withUnliftStrategy :: forall (es :: [Effect]) a.
(IOE :> es) =>
UnliftStrategy -> Eff es a -> Eff es a
withUnliftStrategy UnliftStrategy
unlift = (StaticRep IOE -> StaticRep IOE) -> Eff es a -> Eff es a
forall (e :: Effect) (sideEffects :: SideEffects) (es :: [Effect])
a.
(HasCallStack, DispatchOf e ~ 'Static sideEffects, e :> es) =>
(StaticRep e -> StaticRep e) -> Eff es a -> Eff es a
localStaticRep ((StaticRep IOE -> StaticRep IOE) -> Eff es a -> Eff es a)
-> (StaticRep IOE -> StaticRep IOE) -> Eff es a -> Eff es a
forall a b. (a -> b) -> a -> b
$ \StaticRep IOE
_ -> UnliftStrategy -> StaticRep IOE
IOE UnliftStrategy
unlift
withSeqEffToIO
:: (HasCallStack, IOE :> es)
=> ((forall r. Eff es r -> IO r) -> IO a)
-> Eff es a
withSeqEffToIO :: forall (es :: [Effect]) a.
(HasCallStack, IOE :> es) =>
((forall r. Eff es r -> IO r) -> IO a) -> Eff es a
withSeqEffToIO (forall r. Eff es r -> IO r) -> IO 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 -> 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
k
{-# INLINE withSeqEffToIO #-}
withEffToIO
:: (HasCallStack, IOE :> es)
=> UnliftStrategy
-> ((forall r. Eff es r -> IO r) -> IO a)
-> Eff es a
withEffToIO :: forall (es :: [Effect]) a.
(HasCallStack, IOE :> es) =>
UnliftStrategy
-> ((forall r. Eff es r -> IO r) -> IO a) -> Eff es a
withEffToIO UnliftStrategy
strategy (forall r. Eff es r -> IO r) -> IO 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 -> 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
k
UnliftStrategy
SeqForkUnlift -> (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 -> 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
seqForkUnliftIO Env es
es (forall r. Eff es r -> IO r) -> IO a
k
ConcUnlift Persistence
p Limit
b -> (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 -> 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
b (forall r. Eff es r -> IO r) -> IO a
k
{-# INLINE withEffToIO #-}
withConcEffToIO
:: (HasCallStack, IOE :> es)
=> Persistence
-> Limit
-> ((forall r. Eff es r -> IO r) -> IO a)
-> Eff es a
withConcEffToIO :: forall (es :: [Effect]) a.
(HasCallStack, IOE :> es) =>
Persistence
-> Limit -> ((forall r. Eff es r -> IO r) -> IO a) -> Eff es a
withConcEffToIO Persistence
persistence Limit
limit (forall r. Eff es r -> IO r) -> IO 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 ->
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
persistence Limit
limit (forall r. Eff es r -> IO r) -> IO a
k
{-# DEPRECATED withConcEffToIO "Use withEffToIO with the appropriate strategy." #-}
seqUnliftIO
:: HasCallStack
=> Env es
-> ((forall r. Eff es r -> IO r) -> IO a)
-> IO a
seqUnliftIO :: 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
k = do
ThreadId
tid0 <- IO ThreadId
myThreadId
(forall r. Eff es r -> IO r) -> IO a
k ((forall r. Eff es r -> IO r) -> IO a)
-> (forall r. Eff es r -> IO r) -> IO a
forall a b. (a -> b) -> a -> b
$ \Eff es r
m -> do
ThreadId
tid <- IO ThreadId
myThreadId
if ThreadId
tid ThreadId -> ThreadId -> Bool
`eqThreadId` ThreadId
tid0
then Eff es r -> Env es -> IO r
forall (es :: [Effect]) a. Eff es a -> Env es -> IO a
unEff Eff es r
m Env es
es
else [Char] -> IO r
forall a. HasCallStack => [Char] -> a
error
([Char] -> IO r) -> [Char] -> IO r
forall a b. (a -> b) -> a -> b
$ [Char]
"If you want to use the unlifting function to run Eff computations "
[Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ [Char]
"in multiple threads, have a look at UnliftStrategy (ConcUnlift)."
seqForkUnliftIO
:: HasCallStack
=> Env es
-> ((forall r. Eff es r -> IO r) -> IO a)
-> IO a
seqForkUnliftIO :: forall (es :: [Effect]) a.
HasCallStack =>
Env es -> ((forall r. Eff es r -> IO r) -> IO a) -> IO a
seqForkUnliftIO Env es
es0 (forall r. Eff es r -> IO r) -> IO a
k = Env es -> IO (Env es)
forall (es :: [Effect]). HasCallStack => Env es -> IO (Env es)
cloneEnv Env es
es0 IO (Env es) -> (Env es -> IO a) -> IO a
forall a b. IO a -> (a -> IO b) -> IO b
forall (m :: Type -> Type) a b. Monad m => m a -> (a -> m b) -> m b
>>= \Env es
es -> 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
k
{-# INLINE seqForkUnliftIO #-}
concUnliftIO
:: HasCallStack
=> Env es
-> Persistence
-> Limit
-> ((forall r. Eff es r -> IO r) -> IO a)
-> IO a
concUnliftIO :: 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
Ephemeral (Limited Int
uses) = Env es -> Int -> ((forall r. Eff es r -> IO r) -> IO a) -> IO a
forall (m :: Type -> Type) (es :: [Effect]) a.
(HasCallStack, forall r. Coercible (m r) (Env es -> IO r)) =>
Env es -> Int -> ((forall r. m r -> IO r) -> IO a) -> IO a
ephemeralConcUnlift Env es
es Int
uses
concUnliftIO Env es
es Persistence
Ephemeral Limit
Unlimited = Env es -> Int -> ((forall r. Eff es r -> IO r) -> IO a) -> IO a
forall (m :: Type -> Type) (es :: [Effect]) a.
(HasCallStack, forall r. Coercible (m r) (Env es -> IO r)) =>
Env es -> Int -> ((forall r. m r -> IO r) -> IO a) -> IO a
ephemeralConcUnlift Env es
es Int
forall a. Bounded a => a
maxBound
concUnliftIO Env es
es Persistence
Persistent (Limited Int
threads) = Env es
-> Bool -> Int -> ((forall r. Eff es r -> IO r) -> IO a) -> IO a
forall (m :: Type -> Type) (es :: [Effect]) a.
(HasCallStack, forall r. Coercible (m r) (Env es -> IO r)) =>
Env es -> Bool -> Int -> ((forall r. m r -> IO r) -> IO a) -> IO a
persistentConcUnlift Env es
es Bool
False Int
threads
concUnliftIO Env es
es Persistence
Persistent Limit
Unlimited = Env es
-> Bool -> Int -> ((forall r. Eff es r -> IO r) -> IO a) -> IO a
forall (m :: Type -> Type) (es :: [Effect]) a.
(HasCallStack, forall r. Coercible (m r) (Env es -> IO r)) =>
Env es -> Bool -> Int -> ((forall r. m r -> IO r) -> IO a) -> IO a
persistentConcUnlift Env es
es Bool
True Int
forall a. Bounded a => a
maxBound
instance Functor (Eff es) where
fmap :: forall a b. (a -> b) -> Eff es a -> Eff es b
fmap a -> b
f (Eff Env es -> IO 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 -> a -> b
f (a -> b) -> IO a -> IO b
forall (f :: Type -> Type) a b. Functor f => (a -> b) -> f a -> f b
<$> Env es -> IO a
m Env es
es
a
a <$ :: forall a b. a -> Eff es b -> Eff es a
<$ Eff Env es -> IO b
fb = (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 -> a
a a -> IO b -> IO a
forall a b. a -> IO b -> IO a
forall (f :: Type -> Type) a b. Functor f => a -> f b -> f a
<$ Env es -> IO b
fb Env es
es
instance Applicative (Eff es) where
pure :: forall a. a -> Eff es a
pure = IO a -> Eff es a
forall a (es :: [Effect]). IO a -> Eff es a
unsafeEff_ (IO a -> Eff es a) -> (a -> IO a) -> a -> Eff es a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. a -> IO a
forall a. a -> IO a
forall (f :: Type -> Type) a. Applicative f => a -> f a
pure
Eff Env es -> IO (a -> b)
mf <*> :: forall a b. Eff es (a -> b) -> Eff es a -> Eff es b
<*> Eff Env es -> IO a
mx = (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 -> Env es -> IO (a -> b)
mf Env es
es IO (a -> b) -> IO a -> IO b
forall a b. IO (a -> b) -> IO a -> IO b
forall (f :: Type -> Type) a b.
Applicative f =>
f (a -> b) -> f a -> f b
<*> Env es -> IO a
mx Env es
es
Eff Env es -> IO a
ma *> :: forall a b. Eff es a -> Eff es b -> Eff es b
*> Eff Env es -> IO b
mb = (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 -> Env es -> IO a
ma Env es
es IO a -> IO b -> IO b
forall a b. IO a -> IO b -> IO b
forall (f :: Type -> Type) a b. Applicative f => f a -> f b -> f b
*> Env es -> IO b
mb Env es
es
Eff Env es -> IO a
ma <* :: forall a b. Eff es a -> Eff es b -> Eff es a
<* Eff Env es -> IO b
mb = (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 -> Env es -> IO a
ma Env es
es IO a -> IO b -> IO a
forall a b. IO a -> IO b -> IO a
forall (f :: Type -> Type) a b. Applicative f => f a -> f b -> f a
<* Env es -> IO b
mb Env es
es
liftA2 :: forall a b c. (a -> b -> c) -> Eff es a -> Eff es b -> Eff es c
liftA2 a -> b -> c
f (Eff Env es -> IO a
ma) (Eff Env es -> IO b
mb) = (Env es -> IO c) -> Eff es c
forall (es :: [Effect]) a. (Env es -> IO a) -> Eff es a
unsafeEff ((Env es -> IO c) -> Eff es c) -> (Env es -> IO c) -> Eff es c
forall a b. (a -> b) -> a -> b
$ \Env es
es -> (a -> b -> c) -> IO a -> IO b -> IO c
forall a b c. (a -> b -> c) -> IO a -> IO b -> IO c
forall (f :: Type -> Type) a b c.
Applicative f =>
(a -> b -> c) -> f a -> f b -> f c
liftA2 a -> b -> c
f (Env es -> IO a
ma Env es
es) (Env es -> IO b
mb Env es
es)
instance Monad (Eff es) where
return :: forall a. a -> Eff es a
return = IO a -> Eff es a
forall a (es :: [Effect]). IO a -> Eff es a
unsafeEff_ (IO a -> Eff es a) -> (a -> IO a) -> a -> Eff es a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. a -> IO a
forall a. a -> IO a
forall (f :: Type -> Type) a. Applicative f => a -> f a
pure
Eff Env es -> IO a
m >>= :: forall a b. Eff es a -> (a -> Eff es b) -> Eff es b
>>= a -> Eff es b
k = (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 -> Env es -> IO a
m Env es
es IO a -> (a -> IO b) -> IO b
forall a b. IO a -> (a -> IO b) -> IO b
forall (m :: Type -> Type) a b. Monad m => m a -> (a -> m b) -> m b
>>= \a
a -> Eff es b -> Env es -> IO b
forall (es :: [Effect]) a. Eff es a -> Env es -> IO a
unEff (a -> Eff es b
k a
a) Env es
es
Eff Env es -> IO a
ma >> :: forall a b. Eff es a -> Eff es b -> Eff es b
>> Eff Env es -> IO b
mb = (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 -> Env es -> IO a
ma Env es
es IO a -> IO b -> IO b
forall a b. IO a -> IO b -> IO b
forall (m :: Type -> Type) a b. Monad m => m a -> m b -> m b
>> Env es -> IO b
mb Env es
es
instance MonadFix (Eff es) where
mfix :: forall a. (a -> Eff es a) -> Eff es a
mfix a -> Eff es a
f = (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 -> (a -> IO a) -> IO a
forall a. (a -> IO a) -> IO a
forall (m :: Type -> Type) a. MonadFix m => (a -> m a) -> m a
mfix ((a -> IO a) -> IO a) -> (a -> IO a) -> IO a
forall a b. (a -> b) -> a -> b
$ \a
a -> Eff es a -> Env es -> IO a
forall (es :: [Effect]) a. Eff es a -> Env es -> IO a
unEff (a -> Eff es a
f a
a) Env es
es
data NonDet :: Effect where
Empty :: NonDet m a
(:<|>:) :: m a -> m a -> NonDet m a
type instance DispatchOf NonDet = Dynamic
instance NonDet :> es => Alternative (Eff es) where
empty :: forall a. Eff es a
empty = NonDet (Eff es) a -> Eff es a
forall (e :: Effect) (es :: [Effect]) a.
(HasCallStack, DispatchOf e ~ 'Dynamic, e :> es) =>
e (Eff es) a -> Eff es a
send NonDet (Eff es) a
forall (m :: Type -> Type) a. NonDet m a
Empty
Eff es a
a <|> :: forall a. Eff es a -> Eff es a -> Eff es a
<|> Eff es a
b = NonDet (Eff es) a -> Eff es a
forall (e :: Effect) (es :: [Effect]) a.
(HasCallStack, DispatchOf e ~ 'Dynamic, e :> es) =>
e (Eff es) a -> Eff es a
send (Eff es a
a Eff es a -> Eff es a -> NonDet (Eff es) a
forall (m :: Type -> Type) a. m a -> m a -> NonDet m a
:<|>: Eff es a
b)
instance NonDet :> es => MonadPlus (Eff es)
instance C.MonadThrow (Eff es) where
throwM :: forall e a. (HasCallStack, Exception e) => e -> Eff es a
throwM = IO a -> Eff es a
forall a (es :: [Effect]). IO a -> Eff es a
unsafeEff_ (IO a -> Eff es a) -> (e -> IO a) -> e -> Eff es a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. e -> IO a
forall e a. Exception e => e -> IO a
E.throwIO
instance C.MonadCatch (Eff es) where
catch :: forall e a.
(HasCallStack, Exception e) =>
Eff es a -> (e -> Eff es a) -> Eff es a
catch Eff es a
m e -> Eff es a
handler = (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 Eff es a
m Env es
es IO a -> (e -> IO a) -> IO a
forall e a. Exception e => IO a -> (e -> IO a) -> IO a
`E.catch` \e
e -> do
Eff es a -> Env es -> IO a
forall (es :: [Effect]) a. Eff es a -> Env es -> IO a
unEff (e -> Eff es a
handler e
e) Env es
es
instance C.MonadMask (Eff es) where
mask :: forall b.
HasCallStack =>
((forall a. Eff es a -> Eff es a) -> Eff es b) -> Eff es b
mask (forall a. Eff es a -> Eff es a) -> Eff es b
k = (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 -> ((forall a. IO a -> IO a) -> IO b) -> IO b
forall b. ((forall a. IO a -> IO a) -> IO b) -> IO b
E.mask (((forall a. IO a -> IO a) -> IO b) -> IO b)
-> ((forall a. IO a -> IO a) -> IO b) -> IO b
forall a b. (a -> b) -> a -> b
$ \forall a. IO a -> IO a
unmask ->
Eff es b -> Env es -> IO b
forall (es :: [Effect]) a. Eff es a -> Env es -> IO a
unEff ((forall a. Eff es a -> Eff es a) -> Eff es b
k ((forall a. Eff es a -> Eff es a) -> Eff es b)
-> (forall a. Eff es a -> Eff es a) -> Eff es b
forall a b. (a -> b) -> a -> b
$ \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
$ IO a -> IO a
forall a. IO a -> IO a
unmask (IO a -> IO a) -> (Env es -> IO a) -> Env es -> IO a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. 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
uninterruptibleMask :: forall b.
HasCallStack =>
((forall a. Eff es a -> Eff es a) -> Eff es b) -> Eff es b
uninterruptibleMask (forall a. Eff es a -> Eff es a) -> Eff es b
k = (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 -> ((forall a. IO a -> IO a) -> IO b) -> IO b
forall b. ((forall a. IO a -> IO a) -> IO b) -> IO b
E.uninterruptibleMask (((forall a. IO a -> IO a) -> IO b) -> IO b)
-> ((forall a. IO a -> IO a) -> IO b) -> IO b
forall a b. (a -> b) -> a -> b
$ \forall a. IO a -> IO a
unmask ->
Eff es b -> Env es -> IO b
forall (es :: [Effect]) a. Eff es a -> Env es -> IO a
unEff ((forall a. Eff es a -> Eff es a) -> Eff es b
k ((forall a. Eff es a -> Eff es a) -> Eff es b)
-> (forall a. Eff es a -> Eff es a) -> Eff es b
forall a b. (a -> b) -> a -> b
$ \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
$ IO a -> IO a
forall a. IO a -> IO a
unmask (IO a -> IO a) -> (Env es -> IO a) -> Env es -> IO a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. 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
generalBracket :: forall a b c.
HasCallStack =>
Eff es a
-> (a -> ExitCase b -> Eff es c)
-> (a -> Eff es b)
-> Eff es (b, c)
generalBracket Eff es a
acquire a -> ExitCase b -> Eff es c
release a -> Eff es b
use = (Env es -> IO (b, c)) -> Eff es (b, c)
forall (es :: [Effect]) a. (Env es -> IO a) -> Eff es a
unsafeEff ((Env es -> IO (b, c)) -> Eff es (b, c))
-> (Env es -> IO (b, c)) -> Eff es (b, c)
forall a b. (a -> b) -> a -> b
$ \Env es
es -> ((forall a. IO a -> IO a) -> IO (b, c)) -> IO (b, c)
forall b. ((forall a. IO a -> IO a) -> IO b) -> IO b
E.mask (((forall a. IO a -> IO a) -> IO (b, c)) -> IO (b, c))
-> ((forall a. IO a -> IO a) -> IO (b, c)) -> IO (b, c)
forall a b. (a -> b) -> a -> b
$ \forall a. IO a -> IO a
unmask -> do
a
resource <- Eff es a -> Env es -> IO a
forall (es :: [Effect]) a. Eff es a -> Env es -> IO a
unEff Eff es a
acquire Env es
es
b
b <- IO b -> IO b
forall a. IO a -> IO a
unmask (Eff es b -> Env es -> IO b
forall (es :: [Effect]) a. Eff es a -> Env es -> IO a
unEff (a -> Eff es b
use a
resource) Env es
es) IO b -> (SomeException -> IO b) -> IO b
forall e a. Exception e => IO a -> (e -> IO a) -> IO a
`E.catch` \SomeException
e -> do
c
_ <- Eff es c -> Env es -> IO c
forall (es :: [Effect]) a. Eff es a -> Env es -> IO a
unEff (a -> ExitCase b -> Eff es c
release a
resource (ExitCase b -> Eff es c) -> ExitCase b -> Eff es c
forall a b. (a -> b) -> a -> b
$ SomeException -> ExitCase b
forall a. SomeException -> ExitCase a
C.ExitCaseException SomeException
e) Env es
es
SomeException -> IO b
forall e a. Exception e => e -> IO a
E.throwIO SomeException
e
c
c <- Eff es c -> Env es -> IO c
forall (es :: [Effect]) a. Eff es a -> Env es -> IO a
unEff (a -> ExitCase b -> Eff es c
release a
resource (ExitCase b -> Eff es c) -> ExitCase b -> Eff es c
forall a b. (a -> b) -> a -> b
$ b -> ExitCase b
forall a. a -> ExitCase a
C.ExitCaseSuccess b
b) Env es
es
(b, c) -> IO (b, c)
forall a. a -> IO a
forall (f :: Type -> Type) a. Applicative f => a -> f a
pure (b
b, c
c)
data Fail :: Effect where
Fail :: String -> Fail m a
type instance DispatchOf Fail = Dynamic
instance Fail :> es => MonadFail (Eff es) where
fail :: forall a. [Char] -> Eff es a
fail [Char]
msg = Fail (Eff es) a -> Eff es a
forall (e :: Effect) (es :: [Effect]) a.
(HasCallStack, DispatchOf e ~ 'Dynamic, e :> es) =>
e (Eff es) a -> Eff es a
send ([Char] -> Fail (Eff es) a
forall (m :: Type -> Type) a. [Char] -> Fail m a
Fail [Char]
msg)
data IOE :: Effect
type instance DispatchOf IOE = Static WithSideEffects
newtype instance StaticRep IOE = IOE UnliftStrategy
runEff :: HasCallStack => Eff '[IOE] a -> IO a
runEff :: forall a. HasCallStack => Eff '[IOE] a -> IO a
runEff Eff '[IOE] a
m = Eff '[IOE] a -> Env '[IOE] -> IO a
forall (es :: [Effect]) a. Eff es a -> Env es -> IO a
unEff Eff '[IOE] a
m (Env '[IOE] -> IO a) -> IO (Env '[IOE]) -> IO a
forall (m :: Type -> Type) a b. Monad m => (a -> m b) -> m a -> m b
=<< EffectRep (DispatchOf IOE) IOE
-> Relinker (EffectRep (DispatchOf IOE)) IOE
-> Env '[]
-> IO (Env '[IOE])
forall (e :: Effect) (es :: [Effect]).
HasCallStack =>
EffectRep (DispatchOf e) e
-> Relinker (EffectRep (DispatchOf e)) e
-> Env es
-> IO (Env (e : es))
consEnv (UnliftStrategy -> StaticRep IOE
IOE UnliftStrategy
SeqUnlift) Relinker (EffectRep (DispatchOf IOE)) IOE
Relinker StaticRep IOE
forall (rep :: Effect -> Type) (e :: Effect). Relinker rep e
dummyRelinker (Env '[] -> IO (Env '[IOE])) -> IO (Env '[]) -> IO (Env '[IOE])
forall (m :: Type -> Type) a b. Monad m => (a -> m b) -> m a -> m b
=<< IO (Env '[])
HasCallStack => IO (Env '[])
emptyEnv
instance IOE :> es => MonadIO (Eff es) where
liftIO :: forall a. IO a -> Eff es a
liftIO = IO a -> Eff es a
forall a (es :: [Effect]). IO a -> Eff es a
unsafeEff_
instance IOE :> es => MonadUnliftIO (Eff es) where
withRunInIO :: forall b. ((forall a. Eff es a -> IO a) -> IO b) -> Eff es b
withRunInIO (forall a. Eff es a -> IO a) -> IO b
k = Eff es UnliftStrategy
forall (es :: [Effect]). (IOE :> es) => Eff es UnliftStrategy
unliftStrategy Eff es UnliftStrategy -> (UnliftStrategy -> Eff es b) -> Eff es b
forall a b. Eff es a -> (a -> Eff es b) -> Eff es b
forall (m :: Type -> Type) a b. Monad m => m a -> (a -> m b) -> m b
>>= (UnliftStrategy
-> ((forall a. Eff es a -> IO a) -> IO b) -> Eff es b
forall (es :: [Effect]) a.
(HasCallStack, IOE :> es) =>
UnliftStrategy
-> ((forall r. Eff es r -> IO r) -> IO a) -> Eff es a
`withEffToIO` (forall a. Eff es a -> IO a) -> IO b
k)
instance IOE :> es => MonadBase IO (Eff es) where
liftBase :: forall α. IO α -> Eff es α
liftBase = IO α -> Eff es α
forall a (es :: [Effect]). IO a -> Eff es a
unsafeEff_
instance IOE :> es => MonadBaseControl IO (Eff es) where
type StM (Eff es) a = a
liftBaseWith :: forall a. (RunInBase (Eff es) IO -> IO a) -> Eff es a
liftBaseWith RunInBase (Eff es) IO -> IO a
k = Eff es UnliftStrategy
forall (es :: [Effect]). (IOE :> es) => Eff es UnliftStrategy
unliftStrategy Eff es UnliftStrategy -> (UnliftStrategy -> Eff es a) -> Eff es a
forall a b. Eff es a -> (a -> Eff es b) -> Eff es b
forall (m :: Type -> Type) a b. Monad m => m a -> (a -> m b) -> m b
>>= (UnliftStrategy
-> ((forall r. Eff es r -> IO r) -> IO a) -> Eff es a
forall (es :: [Effect]) a.
(HasCallStack, IOE :> es) =>
UnliftStrategy
-> ((forall r. Eff es r -> IO r) -> IO a) -> Eff es a
`withEffToIO` (forall r. Eff es r -> IO r) -> IO a
RunInBase (Eff es) IO -> IO a
k)
restoreM :: forall a. StM (Eff es) a -> Eff es a
restoreM = a -> Eff es a
StM (Eff es) a -> Eff es a
forall a. a -> Eff es a
forall (f :: Type -> Type) a. Applicative f => a -> f a
pure
data Prim :: Effect
type instance DispatchOf Prim = Static WithSideEffects
data instance StaticRep Prim = Prim
data PrimStateEff
runPrim :: (HasCallStack, IOE :> es) => Eff (Prim : es) a -> Eff es a
runPrim :: forall (es :: [Effect]) a.
(HasCallStack, IOE :> es) =>
Eff (Prim : es) a -> Eff es a
runPrim = StaticRep Prim -> Eff (Prim : es) a -> Eff es a
forall (e :: Effect) (sideEffects :: SideEffects) (es :: [Effect])
a.
(HasCallStack, DispatchOf e ~ 'Static sideEffects,
MaybeIOE sideEffects es) =>
StaticRep e -> Eff (e : es) a -> Eff es a
evalStaticRep StaticRep Prim
Prim
instance Prim :> es => PrimMonad (Eff es) where
type PrimState (Eff es) = PrimStateEff
primitive :: forall a.
(State# (PrimState (Eff es))
-> (# State# (PrimState (Eff es)), a #))
-> Eff es a
primitive = IO a -> Eff es a
forall a (es :: [Effect]). IO a -> Eff es a
unsafeEff_ (IO a -> Eff es a)
-> ((State# PrimStateEff -> (# State# PrimStateEff, a #)) -> IO a)
-> (State# PrimStateEff -> (# State# PrimStateEff, a #))
-> Eff es a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (State# RealWorld -> (# State# RealWorld, a #)) -> IO a
forall a. (State# RealWorld -> (# State# RealWorld, a #)) -> IO a
IO ((State# RealWorld -> (# State# RealWorld, a #)) -> IO a)
-> ((State# PrimStateEff -> (# State# PrimStateEff, a #))
-> State# RealWorld -> (# State# RealWorld, a #))
-> (State# PrimStateEff -> (# State# PrimStateEff, a #))
-> IO a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (State# PrimStateEff -> (# State# PrimStateEff, a #))
-> State# RealWorld -> (# State# RealWorld, a #)
forall a b. a -> b
unsafeCoerce
raise :: Eff es a -> Eff (e : es) a
raise :: forall (es :: [Effect]) a (e :: Effect). Eff es a -> Eff (e : es) a
raise Eff es a
m = (Env (e : es) -> IO a) -> Eff (e : es) a
forall (es :: [Effect]) a. (Env es -> IO a) -> Eff es a
unsafeEff ((Env (e : es) -> IO a) -> Eff (e : es) a)
-> (Env (e : es) -> IO a) -> Eff (e : es) a
forall a b. (a -> b) -> a -> b
$ \Env (e : es)
es -> 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 -> IO a) -> IO (Env es) -> IO a
forall (m :: Type -> Type) a b. Monad m => (a -> m b) -> m a -> m b
=<< Env (e : es) -> IO (Env es)
forall (e :: Effect) (es :: [Effect]). Env (e : es) -> IO (Env es)
tailEnv Env (e : es)
es
raiseWith
:: HasCallStack
=> UnliftStrategy
-> ((forall r. Eff (e : es) r -> Eff es r) -> Eff es a)
-> Eff (e : es) a
raiseWith :: forall (e :: Effect) (es :: [Effect]) a.
HasCallStack =>
UnliftStrategy
-> ((forall r. Eff (e : es) r -> Eff es r) -> Eff es a)
-> Eff (e : es) a
raiseWith UnliftStrategy
strategy (forall r. Eff (e : es) r -> Eff es r) -> Eff es a
k = (Env (e : es) -> IO a) -> Eff (e : es) a
forall (es :: [Effect]) a. (Env es -> IO a) -> Eff es a
unsafeEff ((Env (e : es) -> IO a) -> Eff (e : es) a)
-> (Env (e : es) -> IO a) -> Eff (e : es) a
forall a b. (a -> b) -> a -> b
$ \Env (e : es)
ees -> do
Env es
es <- Env (e : es) -> IO (Env es)
forall (e :: Effect) (es :: [Effect]). Env (e : es) -> IO (Env es)
tailEnv Env (e : es)
ees
case UnliftStrategy
strategy of
UnliftStrategy
SeqUnlift -> 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 -> 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 (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
UnliftStrategy
SeqForkUnlift -> 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
seqForkUnliftIO 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 -> 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 (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 (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 -> 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 (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 raiseWith #-}
subsume :: e :> es => Eff (e : es) a -> Eff es a
subsume :: forall (e :: Effect) (es :: [Effect]) a.
(e :> es) =>
Eff (e : es) a -> Eff es a
subsume 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 -> Eff (e : es) a -> Env (e : es) -> IO a
forall (es :: [Effect]) a. Eff es a -> Env es -> IO a
unEff Eff (e : es) a
m (Env (e : es) -> IO a) -> IO (Env (e : es)) -> IO a
forall (m :: Type -> Type) a b. Monad m => (a -> m b) -> m a -> m b
=<< Env es -> IO (Env (e : es))
forall (e :: Effect) (es :: [Effect]).
(e :> es) =>
Env es -> IO (Env (e : es))
subsumeEnv Env es
es
inject :: Subset subEs es => Eff subEs a -> Eff es a
inject :: forall (subEs :: [Effect]) (es :: [Effect]) a.
Subset subEs es =>
Eff subEs a -> Eff es a
inject Eff subEs 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 -> Eff subEs a -> Env subEs -> IO a
forall (es :: [Effect]) a. Eff es a -> Env es -> IO a
unEff Eff subEs a
m (Env subEs -> IO a) -> IO (Env subEs) -> IO a
forall (m :: Type -> Type) a b. Monad m => (a -> m b) -> m a -> m b
=<< Env es -> IO (Env subEs)
forall (subEs :: [Effect]) (es :: [Effect]).
Subset subEs es =>
Env es -> IO (Env subEs)
injectEnv Env es
es
type role LocalEnv nominal nominal
newtype LocalEnv (localEs :: [Effect]) (handlerEs :: [Effect]) = LocalEnv (Env localEs)
type EffectHandler (e :: Effect) (es :: [Effect])
= forall a localEs. (HasCallStack, e :> localEs)
=> LocalEnv localEs es
-> e (Eff localEs) a
-> Eff es a
data Handler :: Effect -> Type where
Handler :: !(Env handlerEs) -> !(EffectHandler e handlerEs) -> Handler e
type instance EffectRep Dynamic = Handler
relinkHandler :: Relinker Handler e
relinkHandler :: forall (e :: Effect). Relinker Handler e
relinkHandler = (HasCallStack =>
(forall (es :: [Effect]). Env es -> IO (Env es))
-> Handler e -> IO (Handler e))
-> Relinker Handler e
forall (a :: Effect -> Type) (b :: Effect).
(HasCallStack =>
(forall (es :: [Effect]). Env es -> IO (Env es))
-> a b -> IO (a b))
-> Relinker a b
Relinker ((HasCallStack =>
(forall (es :: [Effect]). Env es -> IO (Env es))
-> Handler e -> IO (Handler e))
-> Relinker Handler e)
-> (HasCallStack =>
(forall (es :: [Effect]). Env es -> IO (Env es))
-> Handler e -> IO (Handler e))
-> Relinker Handler e
forall a b. (a -> b) -> a -> b
$ \forall (es :: [Effect]). Env es -> IO (Env es)
relink (Handler Env handlerEs
handlerEs EffectHandler e handlerEs
handler) -> do
Env handlerEs
newHandlerEs <- Env handlerEs -> IO (Env handlerEs)
forall (es :: [Effect]). Env es -> IO (Env es)
relink Env handlerEs
handlerEs
Handler e -> IO (Handler e)
forall a. a -> IO a
forall (f :: Type -> Type) a. Applicative f => a -> f a
pure (Handler e -> IO (Handler e)) -> Handler e -> IO (Handler e)
forall a b. (a -> b) -> a -> b
$ Env handlerEs -> EffectHandler e handlerEs -> Handler e
forall (handlerEs :: [Effect]) (e :: Effect).
Env handlerEs -> EffectHandler e handlerEs -> Handler e
Handler Env handlerEs
newHandlerEs LocalEnv localEs handlerEs -> e (Eff localEs) a -> Eff handlerEs a
EffectHandler e handlerEs
handler
runHandler
:: (HasCallStack, DispatchOf e ~ Dynamic)
=> Handler e
-> Eff (e : es) a
-> Eff es a
runHandler :: forall (e :: Effect) (es :: [Effect]) a.
(HasCallStack, DispatchOf e ~ 'Dynamic) =>
Handler e -> Eff (e : es) a -> Eff es a
runHandler Handler e
e 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
es0 -> do
IO (Env (e : es))
-> (Env (e : es) -> IO ()) -> (Env (e : es) -> IO a) -> IO a
forall a b c. IO a -> (a -> IO b) -> (a -> IO c) -> IO c
inlineBracket
(EffectRep (DispatchOf e) e
-> Relinker (EffectRep (DispatchOf e)) e
-> Env es
-> IO (Env (e : es))
forall (e :: Effect) (es :: [Effect]).
HasCallStack =>
EffectRep (DispatchOf e) e
-> Relinker (EffectRep (DispatchOf e)) e
-> Env es
-> IO (Env (e : es))
consEnv EffectRep (DispatchOf e) e
Handler e
e Relinker (EffectRep (DispatchOf e)) e
Relinker Handler e
forall (e :: Effect). Relinker Handler e
relinkHandler Env es
es0)
Env (e : es) -> IO ()
forall (e :: Effect) (es :: [Effect]).
HasCallStack =>
Env (e : es) -> IO ()
unconsEnv
(\Env (e : es)
es -> Eff (e : es) a -> Env (e : es) -> IO a
forall (es :: [Effect]) a. Eff es a -> Env es -> IO a
unEff Eff (e : es) a
m Env (e : es)
es)
send
:: (HasCallStack, DispatchOf e ~ Dynamic, e :> es)
=> e (Eff es) a
-> Eff es a
send :: forall (e :: Effect) (es :: [Effect]) a.
(HasCallStack, DispatchOf e ~ 'Dynamic, e :> es) =>
e (Eff es) a -> Eff es a
send e (Eff es) a
op = (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
Handler Env handlerEs
handlerEs EffectHandler e handlerEs
handler <- Env es -> IO (EffectRep (DispatchOf e) e)
forall (e :: Effect) (es :: [Effect]).
(HasCallStack, e :> es) =>
Env es -> IO (EffectRep (DispatchOf e) e)
getEnv Env es
es
Eff handlerEs a -> Env handlerEs -> IO a
forall (es :: [Effect]) a. Eff es a -> Env es -> IO a
unEff ((HasCallStack =>
LocalEnv es handlerEs -> e (Eff es) a -> Eff handlerEs a)
-> LocalEnv es handlerEs -> e (Eff es) a -> Eff handlerEs a
forall a. HasCallStack => (HasCallStack => a) -> a
withFrozenCallStack HasCallStack =>
LocalEnv es handlerEs -> e (Eff es) a -> Eff handlerEs a
LocalEnv es handlerEs -> e (Eff es) a -> Eff handlerEs a
EffectHandler e handlerEs
handler (Env es -> LocalEnv es handlerEs
forall (localEs :: [Effect]) (handlerEs :: [Effect]).
Env localEs -> LocalEnv localEs handlerEs
LocalEnv Env es
es) e (Eff es) a
op) Env handlerEs
handlerEs
{-# NOINLINE send #-}
type family MaybeIOE (sideEffects :: SideEffects) (es :: [Effect]) :: Constraint where
MaybeIOE NoSideEffects _ = ()
MaybeIOE WithSideEffects es = IOE :> es
data family StaticRep (e :: Effect) :: Type
type instance EffectRep (Static sideEffects) = StaticRep
runStaticRep
:: (HasCallStack, DispatchOf e ~ Static sideEffects, MaybeIOE sideEffects es)
=> StaticRep e
-> Eff (e : es) a
-> Eff es (a, StaticRep e)
runStaticRep :: forall (e :: Effect) (sideEffects :: SideEffects) (es :: [Effect])
a.
(HasCallStack, DispatchOf e ~ 'Static sideEffects,
MaybeIOE sideEffects es) =>
StaticRep e -> Eff (e : es) a -> Eff es (a, StaticRep e)
runStaticRep StaticRep e
e0 Eff (e : es) a
m = (Env es -> IO (a, StaticRep e)) -> Eff es (a, StaticRep e)
forall (es :: [Effect]) a. (Env es -> IO a) -> Eff es a
unsafeEff ((Env es -> IO (a, StaticRep e)) -> Eff es (a, StaticRep e))
-> (Env es -> IO (a, StaticRep e)) -> Eff es (a, StaticRep e)
forall a b. (a -> b) -> a -> b
$ \Env es
es0 -> do
IO (Env (e : es))
-> (Env (e : es) -> IO ())
-> (Env (e : es) -> IO (a, StaticRep e))
-> IO (a, StaticRep e)
forall a b c. IO a -> (a -> IO b) -> (a -> IO c) -> IO c
inlineBracket
(EffectRep (DispatchOf e) e
-> Relinker (EffectRep (DispatchOf e)) e
-> Env es
-> IO (Env (e : es))
forall (e :: Effect) (es :: [Effect]).
HasCallStack =>
EffectRep (DispatchOf e) e
-> Relinker (EffectRep (DispatchOf e)) e
-> Env es
-> IO (Env (e : es))
consEnv EffectRep (DispatchOf e) e
StaticRep e
e0 Relinker (EffectRep (DispatchOf e)) e
Relinker StaticRep e
forall (rep :: Effect -> Type) (e :: Effect). Relinker rep e
dummyRelinker Env es
es0)
Env (e : es) -> IO ()
forall (e :: Effect) (es :: [Effect]).
HasCallStack =>
Env (e : es) -> IO ()
unconsEnv
(\Env (e : es)
es -> (,) (a -> StaticRep e -> (a, StaticRep e))
-> IO a -> IO (StaticRep e -> (a, StaticRep e))
forall (f :: Type -> Type) a b. Functor f => (a -> b) -> f a -> f b
<$> Eff (e : es) a -> Env (e : es) -> IO a
forall (es :: [Effect]) a. Eff es a -> Env es -> IO a
unEff Eff (e : es) a
m Env (e : es)
es IO (StaticRep e -> (a, StaticRep e))
-> IO (StaticRep e) -> IO (a, StaticRep e)
forall a b. IO (a -> b) -> IO a -> IO b
forall (f :: Type -> Type) a b.
Applicative f =>
f (a -> b) -> f a -> f b
<*> Env (e : es) -> IO (EffectRep (DispatchOf e) e)
forall (e :: Effect) (es :: [Effect]).
(HasCallStack, e :> es) =>
Env es -> IO (EffectRep (DispatchOf e) e)
getEnv Env (e : es)
es)
evalStaticRep
:: (HasCallStack, DispatchOf e ~ Static sideEffects, MaybeIOE sideEffects es)
=> StaticRep e
-> Eff (e : es) a
-> Eff es a
evalStaticRep :: forall (e :: Effect) (sideEffects :: SideEffects) (es :: [Effect])
a.
(HasCallStack, DispatchOf e ~ 'Static sideEffects,
MaybeIOE sideEffects es) =>
StaticRep e -> Eff (e : es) a -> Eff es a
evalStaticRep StaticRep e
e 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
es0 -> do
IO (Env (e : es))
-> (Env (e : es) -> IO ()) -> (Env (e : es) -> IO a) -> IO a
forall a b c. IO a -> (a -> IO b) -> (a -> IO c) -> IO c
inlineBracket
(EffectRep (DispatchOf e) e
-> Relinker (EffectRep (DispatchOf e)) e
-> Env es
-> IO (Env (e : es))
forall (e :: Effect) (es :: [Effect]).
HasCallStack =>
EffectRep (DispatchOf e) e
-> Relinker (EffectRep (DispatchOf e)) e
-> Env es
-> IO (Env (e : es))
consEnv EffectRep (DispatchOf e) e
StaticRep e
e Relinker (EffectRep (DispatchOf e)) e
Relinker StaticRep e
forall (rep :: Effect -> Type) (e :: Effect). Relinker rep e
dummyRelinker Env es
es0)
Env (e : es) -> IO ()
forall (e :: Effect) (es :: [Effect]).
HasCallStack =>
Env (e : es) -> IO ()
unconsEnv
(\Env (e : es)
es -> Eff (e : es) a -> Env (e : es) -> IO a
forall (es :: [Effect]) a. Eff es a -> Env es -> IO a
unEff Eff (e : es) a
m Env (e : es)
es)
execStaticRep
:: (HasCallStack, DispatchOf e ~ Static sideEffects, MaybeIOE sideEffects es)
=> StaticRep e
-> Eff (e : es) a
-> Eff es (StaticRep e)
execStaticRep :: forall (e :: Effect) (sideEffects :: SideEffects) (es :: [Effect])
a.
(HasCallStack, DispatchOf e ~ 'Static sideEffects,
MaybeIOE sideEffects es) =>
StaticRep e -> Eff (e : es) a -> Eff es (StaticRep e)
execStaticRep StaticRep e
e0 Eff (e : es) a
m = (Env es -> IO (StaticRep e)) -> Eff es (StaticRep e)
forall (es :: [Effect]) a. (Env es -> IO a) -> Eff es a
unsafeEff ((Env es -> IO (StaticRep e)) -> Eff es (StaticRep e))
-> (Env es -> IO (StaticRep e)) -> Eff es (StaticRep e)
forall a b. (a -> b) -> a -> b
$ \Env es
es0 -> do
IO (Env (e : es))
-> (Env (e : es) -> IO ())
-> (Env (e : es) -> IO (StaticRep e))
-> IO (StaticRep e)
forall a b c. IO a -> (a -> IO b) -> (a -> IO c) -> IO c
inlineBracket
(EffectRep (DispatchOf e) e
-> Relinker (EffectRep (DispatchOf e)) e
-> Env es
-> IO (Env (e : es))
forall (e :: Effect) (es :: [Effect]).
HasCallStack =>
EffectRep (DispatchOf e) e
-> Relinker (EffectRep (DispatchOf e)) e
-> Env es
-> IO (Env (e : es))
consEnv EffectRep (DispatchOf e) e
StaticRep e
e0 Relinker (EffectRep (DispatchOf e)) e
Relinker StaticRep e
forall (rep :: Effect -> Type) (e :: Effect). Relinker rep e
dummyRelinker Env es
es0)
Env (e : es) -> IO ()
forall (e :: Effect) (es :: [Effect]).
HasCallStack =>
Env (e : es) -> IO ()
unconsEnv
(\Env (e : es)
es -> Eff (e : es) a -> Env (e : es) -> IO a
forall (es :: [Effect]) a. Eff es a -> Env es -> IO a
unEff Eff (e : es) a
m Env (e : es)
es IO a -> IO (StaticRep e) -> IO (StaticRep e)
forall a b. IO a -> IO b -> IO b
forall (f :: Type -> Type) a b. Applicative f => f a -> f b -> f b
*> Env (e : es) -> IO (EffectRep (DispatchOf e) e)
forall (e :: Effect) (es :: [Effect]).
(HasCallStack, e :> es) =>
Env es -> IO (EffectRep (DispatchOf e) e)
getEnv Env (e : es)
es)
getStaticRep
:: (HasCallStack, DispatchOf e ~ Static sideEffects, e :> es)
=> Eff es (StaticRep e)
getStaticRep :: forall (e :: Effect) (sideEffects :: SideEffects) (es :: [Effect]).
(HasCallStack, DispatchOf e ~ 'Static sideEffects, e :> es) =>
Eff es (StaticRep e)
getStaticRep = (Env es -> IO (StaticRep e)) -> Eff es (StaticRep e)
forall (es :: [Effect]) a. (Env es -> IO a) -> Eff es a
unsafeEff ((Env es -> IO (StaticRep e)) -> Eff es (StaticRep e))
-> (Env es -> IO (StaticRep e)) -> Eff es (StaticRep e)
forall a b. (a -> b) -> a -> b
$ \Env es
es -> Env es -> IO (EffectRep (DispatchOf e) e)
forall (e :: Effect) (es :: [Effect]).
(HasCallStack, e :> es) =>
Env es -> IO (EffectRep (DispatchOf e) e)
getEnv Env es
es
putStaticRep
:: (HasCallStack, DispatchOf e ~ Static sideEffects, e :> es)
=> StaticRep e -> Eff es ()
putStaticRep :: forall (e :: Effect) (sideEffects :: SideEffects) (es :: [Effect]).
(HasCallStack, DispatchOf e ~ 'Static sideEffects, e :> es) =>
StaticRep e -> Eff es ()
putStaticRep StaticRep e
s = (Env es -> IO ()) -> Eff es ()
forall (es :: [Effect]) a. (Env es -> IO a) -> Eff es a
unsafeEff ((Env es -> IO ()) -> Eff es ()) -> (Env es -> IO ()) -> Eff es ()
forall a b. (a -> b) -> a -> b
$ \Env es
es -> Env es -> EffectRep (DispatchOf e) e -> IO ()
forall (e :: Effect) (es :: [Effect]).
(HasCallStack, e :> es) =>
Env es -> EffectRep (DispatchOf e) e -> IO ()
putEnv Env es
es EffectRep (DispatchOf e) e
StaticRep e
s
stateStaticRep
:: (HasCallStack, DispatchOf e ~ Static sideEffects, e :> es)
=> (StaticRep e -> (a, StaticRep e))
-> Eff es a
stateStaticRep :: forall (e :: Effect) (sideEffects :: SideEffects) (es :: [Effect])
a.
(HasCallStack, DispatchOf e ~ 'Static sideEffects, e :> es) =>
(StaticRep e -> (a, StaticRep e)) -> Eff es a
stateStaticRep StaticRep e -> (a, StaticRep e)
f = (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 -> Env es
-> (EffectRep (DispatchOf e) e -> (a, EffectRep (DispatchOf e) e))
-> IO a
forall (e :: Effect) (es :: [Effect]) a.
(HasCallStack, e :> es) =>
Env es
-> (EffectRep (DispatchOf e) e -> (a, EffectRep (DispatchOf e) e))
-> IO a
stateEnv Env es
es EffectRep (DispatchOf e) e -> (a, EffectRep (DispatchOf e) e)
StaticRep e -> (a, StaticRep e)
f
stateStaticRepM
:: (HasCallStack, DispatchOf e ~ Static sideEffects, e :> es)
=> (StaticRep e -> Eff es (a, StaticRep e))
-> Eff es a
stateStaticRepM :: forall (e :: Effect) (sideEffects :: SideEffects) (es :: [Effect])
a.
(HasCallStack, DispatchOf e ~ 'Static sideEffects, e :> es) =>
(StaticRep e -> Eff es (a, StaticRep e)) -> Eff es a
stateStaticRepM StaticRep e -> Eff es (a, StaticRep e)
f = (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 -> ((forall a. IO a -> IO a) -> IO a) -> IO a
forall b. ((forall a. IO a -> IO a) -> IO b) -> IO b
E.mask (((forall a. IO a -> IO a) -> IO a) -> IO a)
-> ((forall a. IO a -> IO a) -> IO a) -> IO a
forall a b. (a -> b) -> a -> b
$ \forall a. IO a -> IO a
unmask -> do
(a
a, StaticRep e
e) <- IO (a, StaticRep e) -> IO (a, StaticRep e)
forall a. IO a -> IO a
unmask (IO (a, StaticRep e) -> IO (a, StaticRep e))
-> (StaticRep e -> IO (a, StaticRep e))
-> StaticRep e
-> IO (a, StaticRep e)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Eff es (a, StaticRep e) -> Env es -> IO (a, StaticRep e)
forall (es :: [Effect]) a. Eff es a -> Env es -> IO a
`unEff` Env es
es) (Eff es (a, StaticRep e) -> IO (a, StaticRep e))
-> (StaticRep e -> Eff es (a, StaticRep e))
-> StaticRep e
-> IO (a, StaticRep e)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. StaticRep e -> Eff es (a, StaticRep e)
f (StaticRep e -> IO (a, StaticRep e))
-> IO (StaticRep e) -> IO (a, StaticRep e)
forall (m :: Type -> Type) a b. Monad m => (a -> m b) -> m a -> m b
=<< Env es -> IO (EffectRep (DispatchOf e) e)
forall (e :: Effect) (es :: [Effect]).
(HasCallStack, e :> es) =>
Env es -> IO (EffectRep (DispatchOf e) e)
getEnv Env es
es
Env es -> EffectRep (DispatchOf e) e -> IO ()
forall (e :: Effect) (es :: [Effect]).
(HasCallStack, e :> es) =>
Env es -> EffectRep (DispatchOf e) e -> IO ()
putEnv Env es
es EffectRep (DispatchOf e) e
StaticRep e
e
a -> IO a
forall a. a -> IO a
forall (f :: Type -> Type) a. Applicative f => a -> f a
pure a
a
localStaticRep
:: (HasCallStack, DispatchOf e ~ Static sideEffects, e :> es)
=> (StaticRep e -> StaticRep e)
-> Eff es a
-> Eff es a
localStaticRep :: forall (e :: Effect) (sideEffects :: SideEffects) (es :: [Effect])
a.
(HasCallStack, DispatchOf e ~ 'Static sideEffects, e :> es) =>
(StaticRep e -> StaticRep e) -> Eff es a -> Eff es a
localStaticRep StaticRep e -> StaticRep e
f 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 (EffectRep (DispatchOf e) e)
-> (EffectRep (DispatchOf e) e -> IO ())
-> (EffectRep (DispatchOf e) e -> IO a)
-> IO a
forall a b c. IO a -> (a -> IO b) -> (a -> IO c) -> IO c
inlineBracket
(Env es
-> (EffectRep (DispatchOf e) e
-> (EffectRep (DispatchOf e) e, EffectRep (DispatchOf e) e))
-> IO (EffectRep (DispatchOf e) e)
forall (e :: Effect) (es :: [Effect]) a.
(HasCallStack, e :> es) =>
Env es
-> (EffectRep (DispatchOf e) e -> (a, EffectRep (DispatchOf e) e))
-> IO a
stateEnv Env es
es ((EffectRep (DispatchOf e) e
-> (EffectRep (DispatchOf e) e, EffectRep (DispatchOf e) e))
-> IO (EffectRep (DispatchOf e) e))
-> (EffectRep (DispatchOf e) e
-> (EffectRep (DispatchOf e) e, EffectRep (DispatchOf e) e))
-> IO (EffectRep (DispatchOf e) e)
forall a b. (a -> b) -> a -> b
$ \EffectRep (DispatchOf e) e
s -> (EffectRep (DispatchOf e) e
s, StaticRep e -> StaticRep e
f EffectRep (DispatchOf e) e
StaticRep e
s))
(\EffectRep (DispatchOf e) e
s -> Env es -> EffectRep (DispatchOf e) e -> IO ()
forall (e :: Effect) (es :: [Effect]).
(HasCallStack, e :> es) =>
Env es -> EffectRep (DispatchOf e) e -> IO ()
putEnv Env es
es EffectRep (DispatchOf e) e
s)
(\EffectRep (DispatchOf e) e
_ -> 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)