{-# LANGUAGE UndecidableInstances #-}
{-# OPTIONS_GHC -Wno-noncanonical-monad-instances #-}
{-# 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
, withEffToIO
, withSeqEffToIO
, withConcEffToIO
, seqUnliftIO
, concUnliftIO
, EffectHandler
, LocalEnv(..)
, Handler(..)
, relinkHandler
, runHandler
, send
, StaticRep
, MaybeIOE
, runStaticRep
, evalStaticRep
, execStaticRep
, getStaticRep
, putStaticRep
, stateStaticRep
, stateStaticRepM
, localStaticRep
, consEnv
, getEnv
, putEnv
, stateEnv
, modifyEnv
) where
import Control.Applicative
import Control.Monad
import Control.Monad.Base
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 qualified Control.Exception as E
import qualified Control.Monad.Catch as C
import Effectful.Internal.Effect
import Effectful.Internal.Env
import Effectful.Internal.Unlift
type role Eff nominal representational
newtype Eff (es :: [Effect]) a = Eff (Env es -> IO a)
deriving (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
mconcat :: [Eff es a] -> Eff es a
$cmconcat :: forall (es :: [Effect]) a. Monoid a => [Eff es a] -> Eff es a
mappend :: Eff es a -> Eff es a -> Eff es a
$cmappend :: forall (es :: [Effect]) a.
Monoid a =>
Eff es a -> Eff es a -> Eff es a
mempty :: Eff es a
$cmempty :: forall (es :: [Effect]) a. Monoid a => Eff es a
Monoid, NonEmpty (Eff es a) -> Eff es a
Eff es a -> Eff es a -> 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
stimes :: forall b. Integral b => b -> Eff es a -> Eff es a
$cstimes :: forall (es :: [Effect]) a b.
(Semigroup a, Integral b) =>
b -> Eff es a -> Eff es a
sconcat :: NonEmpty (Eff es a) -> Eff es a
$csconcat :: forall (es :: [Effect]) a.
Semigroup a =>
NonEmpty (Eff es a) -> Eff es a
<> :: Eff es a -> Eff es a -> Eff es a
$c<> :: forall (es :: [Effect]) a.
Semigroup a =>
Eff es a -> Eff es a -> Eff es a
Semigroup)
runPureEff :: Eff '[] a -> a
runPureEff :: forall a. Eff '[] a -> a
runPureEff (Eff Env '[] -> IO a
m) =
forall a. IO a -> a
unsafeDupablePerformIO forall a b. (a -> b) -> a -> b
$ Env '[] -> IO a
m forall (m :: Type -> Type) a b. Monad m => (a -> m b) -> m a -> m b
=<< 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 = forall (es :: [Effect]) a. (Env es -> IO a) -> Eff es a
Eff (oneShot :: 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 = forall (es :: [Effect]) a. (Env es -> IO a) -> Eff es a
unsafeEff 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 <- forall (e :: Effect) (sideEffects :: SideEffects) (es :: [Effect]).
(DispatchOf e ~ 'Static sideEffects, e :> es) =>
Eff es (StaticRep e)
getStaticRep
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 = forall (e :: Effect) (sideEffects :: SideEffects) (es :: [Effect])
a.
(DispatchOf e ~ 'Static sideEffects, e :> es) =>
(StaticRep e -> StaticRep e) -> Eff es a -> Eff es a
localStaticRep forall a b. (a -> b) -> a -> b
$ \StaticRep IOE
_ -> UnliftStrategy -> StaticRep IOE
IOE UnliftStrategy
unlift
withEffToIO
:: (HasCallStack, IOE :> es)
=> ((forall r. Eff es r -> IO r) -> IO a)
-> Eff es a
withEffToIO :: forall (es :: [Effect]) a.
(HasCallStack, IOE :> es) =>
((forall r. Eff es r -> IO r) -> IO a) -> Eff es a
withEffToIO (forall r. Eff es r -> IO r) -> IO a
f = forall (es :: [Effect]). (IOE :> es) => Eff es UnliftStrategy
unliftStrategy forall (m :: Type -> Type) a b. Monad m => m a -> (a -> m b) -> m b
>>= \case
UnliftStrategy
SeqUnlift -> forall (es :: [Effect]) a. (Env es -> IO a) -> Eff es a
unsafeEff forall a b. (a -> b) -> a -> b
$ \Env es
es -> 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
f
ConcUnlift Persistence
p Limit
b -> forall (es :: [Effect]) a. (Env es -> IO a) -> Eff es a
unsafeEff forall a b. (a -> b) -> a -> b
$ \Env es
es -> 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
f
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
f = forall (es :: [Effect]) a. (Env es -> IO a) -> Eff es a
unsafeEff forall a b. (a -> b) -> a -> b
$ \Env es
es -> 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
f
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
f = forall (es :: [Effect]) a. (Env es -> IO a) -> Eff es a
unsafeEff forall a b. (a -> b) -> a -> b
$ \Env es
es ->
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
f
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 = forall (m :: Type -> Type) a (es :: [Effect]).
HasCallStack =>
((forall r. m r -> IO r) -> IO a)
-> Env es -> (forall r. m r -> Env es -> IO r) -> IO a
seqUnlift (forall r. Eff es r -> IO r) -> IO a
k Env es
es forall (es :: [Effect]) a. Eff es a -> Env es -> IO a
unEff
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
persistence Limit
limit (forall r. Eff es r -> IO r) -> IO a
k = forall (m :: Type -> Type) a (es :: [Effect]).
HasCallStack =>
Persistence
-> Limit
-> ((forall r. m r -> IO r) -> IO a)
-> Env es
-> (forall r. m r -> Env es -> IO r)
-> IO a
concUnlift Persistence
persistence Limit
limit (forall r. Eff es r -> IO r) -> IO a
k Env es
es forall (es :: [Effect]) a. Eff es a -> Env es -> IO a
unEff
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) = forall (es :: [Effect]) a. (Env es -> IO a) -> Eff es a
unsafeEff forall a b. (a -> b) -> a -> b
$ \Env es
es -> a -> b
f 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 = forall (es :: [Effect]) a. (Env es -> IO a) -> Eff es a
unsafeEff forall a b. (a -> b) -> a -> b
$ \Env es
es -> a
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 = forall a (es :: [Effect]). IO a -> Eff es a
unsafeEff_ forall b c a. (b -> c) -> (a -> b) -> a -> c
. 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 = forall (es :: [Effect]) a. (Env es -> IO a) -> Eff es a
unsafeEff forall a b. (a -> b) -> a -> b
$ \Env es
es -> Env es -> IO (a -> b)
mf Env es
es 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 = forall (es :: [Effect]) a. (Env es -> IO a) -> Eff es a
unsafeEff forall a b. (a -> b) -> a -> b
$ \Env es
es -> Env es -> IO a
ma Env es
es 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 = forall (es :: [Effect]) a. (Env es -> IO a) -> Eff es a
unsafeEff forall a b. (a -> b) -> a -> b
$ \Env es
es -> Env es -> IO a
ma Env es
es 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) = forall (es :: [Effect]) a. (Env es -> IO a) -> Eff es a
unsafeEff forall a b. (a -> b) -> a -> b
$ \Env es
es -> 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 = forall a (es :: [Effect]). IO a -> Eff es a
unsafeEff_ forall b c a. (b -> c) -> (a -> b) -> a -> c
. 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 = forall (es :: [Effect]) a. (Env es -> IO a) -> Eff es a
unsafeEff forall a b. (a -> b) -> a -> b
$ \Env es
es -> Env es -> IO a
m Env es
es forall (m :: Type -> Type) a b. Monad m => m a -> (a -> m b) -> m b
>>= \a
a -> 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 = forall (es :: [Effect]) a. (Env es -> IO a) -> Eff es a
unsafeEff forall a b. (a -> b) -> a -> b
$ \Env es
es -> Env es -> IO a
ma Env es
es 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 = forall (es :: [Effect]) a. (Env es -> IO a) -> Eff es a
unsafeEff forall a b. (a -> b) -> a -> b
$ \Env es
es -> forall (m :: Type -> Type) a. MonadFix m => (a -> m a) -> m a
mfix forall a b. (a -> b) -> a -> b
$ \a
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 = forall a. HasCallStack => (HasCallStack => a) -> a
withFrozenCallStack (forall (e :: Effect) (es :: [Effect]) a.
(HasCallStack, DispatchOf e ~ 'Dynamic, e :> es) =>
e (Eff es) a -> Eff es a
send 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 = forall (e :: Effect) (es :: [Effect]) a.
(HasCallStack, DispatchOf e ~ 'Dynamic, e :> es) =>
e (Eff es) a -> Eff es a
send (Eff es a
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. Exception e => e -> Eff es a
throwM = forall a (es :: [Effect]). IO a -> Eff es a
unsafeEff_ forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall e a. Exception e => e -> IO a
E.throwIO
instance C.MonadCatch (Eff es) where
catch :: forall e a. Exception e => Eff es a -> (e -> Eff es a) -> Eff es a
catch Eff es a
m e -> Eff es a
handler = forall (es :: [Effect]) a. (Env es -> IO a) -> Eff es a
unsafeEff forall a b. (a -> b) -> a -> b
$ \Env es
es -> do
forall (es :: [Effect]) a. Eff es a -> Env es -> IO a
unEff Eff es a
m Env es
es forall e a. Exception e => IO a -> (e -> IO a) -> IO a
`E.catch` \e
e -> do
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.
((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 = forall (es :: [Effect]) a. (Env es -> IO a) -> Eff es a
unsafeEff forall a b. (a -> b) -> a -> b
$ \Env es
es -> forall b. ((forall a. IO a -> IO a) -> IO b) -> IO b
E.mask forall a b. (a -> b) -> a -> b
$ \forall a. IO a -> IO a
unmask ->
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 b. (a -> b) -> a -> b
$ \Eff es a
m -> forall (es :: [Effect]) a. (Env es -> IO a) -> Eff es a
unsafeEff forall a b. (a -> b) -> a -> b
$ forall a. IO a -> IO a
unmask forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall (es :: [Effect]) a. Eff es a -> Env es -> IO a
unEff Eff es a
m) Env es
es
uninterruptibleMask :: forall b.
((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 = forall (es :: [Effect]) a. (Env es -> IO a) -> Eff es a
unsafeEff forall a b. (a -> b) -> a -> b
$ \Env es
es -> forall b. ((forall a. IO a -> IO a) -> IO b) -> IO b
E.uninterruptibleMask forall a b. (a -> b) -> a -> b
$ \forall a. IO a -> IO a
unmask ->
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 b. (a -> b) -> a -> b
$ \Eff es a
m -> forall (es :: [Effect]) a. (Env es -> IO a) -> Eff es a
unsafeEff forall a b. (a -> b) -> a -> b
$ forall a. IO a -> IO a
unmask forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall (es :: [Effect]) a. Eff es a -> Env es -> IO a
unEff Eff es a
m) Env es
es
generalBracket :: forall a b c.
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 = forall (es :: [Effect]) a. (Env es -> IO a) -> Eff es a
unsafeEff forall a b. (a -> b) -> a -> b
$ \Env es
es -> forall b. ((forall a. IO a -> IO a) -> IO b) -> IO b
E.mask forall a b. (a -> b) -> a -> b
$ \forall a. IO a -> IO a
unmask -> do
a
resource <- forall (es :: [Effect]) a. Eff es a -> Env es -> IO a
unEff Eff es a
acquire Env es
es
b
b <- forall a. IO a -> IO a
unmask (forall (es :: [Effect]) a. Eff es a -> Env es -> IO a
unEff (a -> Eff es b
use a
resource) Env es
es) forall e a. Exception e => IO a -> (e -> IO a) -> IO a
`E.catch` \SomeException
e -> do
c
_ <- forall (es :: [Effect]) a. Eff es a -> Env es -> IO a
unEff (a -> ExitCase b -> Eff es c
release a
resource forall a b. (a -> b) -> a -> b
$ forall a. SomeException -> ExitCase a
C.ExitCaseException SomeException
e) Env es
es
forall e a. Exception e => e -> IO a
E.throwIO SomeException
e
c
c <- forall (es :: [Effect]) a. Eff es a -> Env es -> IO a
unEff (a -> ExitCase b -> Eff es c
release a
resource forall a b. (a -> b) -> a -> b
$ forall a. a -> ExitCase a
C.ExitCaseSuccess b
b) Env es
es
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. String -> Eff es a
fail String
msg = forall a. HasCallStack => (HasCallStack => a) -> a
withFrozenCallStack forall a b. (a -> b) -> a -> b
$ forall (e :: Effect) (es :: [Effect]) a.
(HasCallStack, DispatchOf e ~ 'Dynamic, e :> es) =>
e (Eff es) a -> Eff es a
send (forall (m :: Type -> Type) a. String -> Fail m a
Fail String
msg)
data IOE :: Effect
type instance DispatchOf IOE = Static WithSideEffects
newtype instance StaticRep IOE = IOE UnliftStrategy
runEff :: Eff '[IOE] a -> IO a
runEff :: forall a. Eff '[IOE] a -> IO a
runEff Eff '[IOE] a
m = forall (es :: [Effect]) a. Eff es a -> Env es -> IO a
unEff Eff '[IOE] a
m forall (m :: Type -> Type) a b. Monad m => (a -> m b) -> m a -> m b
=<< forall (e :: Effect) (es :: [Effect]).
EffectRep (DispatchOf e) e
-> Relinker (EffectRep (DispatchOf e)) e
-> Env es
-> IO (Env (e : es))
consEnv (UnliftStrategy -> StaticRep IOE
IOE UnliftStrategy
SeqUnlift) forall (rep :: Effect -> Type) (e :: Effect). Relinker rep e
dummyRelinker forall (m :: Type -> Type) a b. Monad m => (a -> m b) -> m a -> m b
=<< IO (Env '[])
emptyEnv
instance IOE :> es => MonadIO (Eff es) where
liftIO :: forall a. IO a -> Eff es a
liftIO = 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 (es :: [Effect]) a.
(HasCallStack, IOE :> es) =>
((forall r. Eff es r -> IO r) -> IO a) -> Eff es a
withEffToIO
instance IOE :> es => MonadBase IO (Eff es) where
liftBase :: forall α. IO α -> Eff es α
liftBase = 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 = forall (es :: [Effect]) a.
(HasCallStack, IOE :> es) =>
((forall r. Eff es r -> IO r) -> IO a) -> Eff es a
withEffToIO
restoreM :: forall a. StM (Eff es) a -> Eff es a
restoreM = 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 :: IOE :> es => Eff (Prim : es) a -> Eff es a
runPrim :: forall (es :: [Effect]) a.
(IOE :> es) =>
Eff (Prim : es) a -> Eff es a
runPrim = forall (e :: Effect) (sideEffects :: SideEffects) (es :: [Effect])
a.
(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 = forall a (es :: [Effect]). IO a -> Eff es a
unsafeEff_ forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. (State# RealWorld -> (# State# RealWorld, a #)) -> IO a
IO forall b c a. (b -> c) -> (a -> b) -> a -> c
. 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 = forall (es :: [Effect]) a. (Env es -> IO a) -> Eff es a
unsafeEff forall a b. (a -> b) -> a -> b
$ \Env (e : es)
es -> forall (es :: [Effect]) a. Eff es a -> Env es -> IO a
unEff Eff es a
m forall (m :: Type -> Type) a b. Monad m => (a -> m b) -> m a -> m b
=<< 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 = case UnliftStrategy
strategy of
UnliftStrategy
SeqUnlift -> forall (es :: [Effect]) a. (Env es -> IO a) -> Eff es a
unsafeEff forall a b. (a -> b) -> a -> b
$ \Env (e : es)
ees -> do
Env es
es <- forall (e :: Effect) (es :: [Effect]). Env (e : es) -> IO (Env es)
tailEnv Env (e : es)
ees
forall (es :: [Effect]) a.
HasCallStack =>
Env es -> ((forall r. Eff es r -> IO r) -> IO a) -> IO a
seqUnliftIO Env (e : es)
ees forall a b. (a -> b) -> a -> b
$ \forall r. Eff (e : es) r -> IO r
unlift -> do
(forall (es :: [Effect]) a. Eff es a -> Env es -> IO a
`unEff` Env es
es) forall a b. (a -> b) -> a -> b
$ (forall r. Eff (e : es) r -> Eff es r) -> Eff es a
k forall a b. (a -> b) -> a -> b
$ forall a (es :: [Effect]). IO a -> Eff es a
unsafeEff_ forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall r. Eff (e : es) r -> IO r
unlift
ConcUnlift Persistence
p Limit
l -> forall (es :: [Effect]) a. (Env es -> IO a) -> Eff es a
unsafeEff forall a b. (a -> b) -> a -> b
$ \Env (e : es)
ees -> do
Env es
es <- forall (e :: Effect) (es :: [Effect]). Env (e : es) -> IO (Env es)
tailEnv Env (e : es)
ees
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 a b. (a -> b) -> a -> b
$ \forall r. Eff (e : es) r -> IO r
unlift -> do
(forall (es :: [Effect]) a. Eff es a -> Env es -> IO a
`unEff` Env es
es) forall a b. (a -> b) -> a -> b
$ (forall r. Eff (e : es) r -> Eff es r) -> Eff es a
k forall a b. (a -> b) -> a -> b
$ forall a (es :: [Effect]). IO a -> Eff es a
unsafeEff_ forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall r. Eff (e : es) r -> IO r
unlift
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 = forall (es :: [Effect]) a. (Env es -> IO a) -> Eff es a
unsafeEff forall a b. (a -> b) -> a -> b
$ \Env es
es -> forall (es :: [Effect]) a. Eff es a -> Env es -> IO a
unEff Eff (e : es) a
m 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 (Env (e : es))
subsumeEnv Env es
es
inject :: Subset xs es => Eff xs a -> Eff es a
inject :: forall (xs :: [Effect]) (es :: [Effect]) a.
Subset xs es =>
Eff xs a -> Eff es a
inject Eff xs a
m = forall (es :: [Effect]) a. (Env es -> IO a) -> Eff es a
unsafeEff forall a b. (a -> b) -> a -> b
$ \Env es
es -> forall (es :: [Effect]) a. Eff es a -> Env es -> IO a
unEff Eff xs a
m forall (m :: Type -> Type) a b. Monad m => (a -> m b) -> m a -> m b
=<< forall (xs :: [Effect]) (es :: [Effect]).
Subset xs es =>
Env es -> IO (Env xs)
injectEnv Env es
es
type role LocalEnv nominal nominal
newtype LocalEnv (localEs :: [Effect]) (handlerEs :: [Effect]) = LocalEnv (Env localEs)
type EffectHandler e es
= forall a localEs. (HasCallStack, e :> localEs)
=> LocalEnv localEs es
-> e (Eff localEs) a
-> Eff es a
data Handler :: Effect -> Type where
Handler :: !(Env es) -> !(EffectHandler e es) -> Handler e
type instance EffectRep Dynamic = Handler
relinkHandler :: Relinker Handler e
relinkHandler :: forall (e :: Effect). Relinker Handler e
relinkHandler = forall (rep :: Effect -> Type) (e :: Effect).
((forall (es :: [Effect]). Env es -> IO (Env es))
-> rep e -> IO (rep e))
-> Relinker rep e
Relinker forall a b. (a -> b) -> a -> b
$ \forall (es :: [Effect]). Env es -> IO (Env es)
relink (Handler Env es
handlerEs EffectHandler e es
handle) -> do
Env es
newHandlerEs <- forall (es :: [Effect]). Env es -> IO (Env es)
relink Env es
handlerEs
forall (f :: Type -> Type) a. Applicative f => a -> f a
pure forall a b. (a -> b) -> a -> b
$ forall (es :: [Effect]) (e :: Effect).
Env es -> EffectHandler e es -> Handler e
Handler Env es
newHandlerEs EffectHandler e es
handle
runHandler :: DispatchOf e ~ Dynamic => Handler e -> Eff (e : es) a -> Eff es a
runHandler :: forall (e :: Effect) (es :: [Effect]) a.
(DispatchOf e ~ 'Dynamic) =>
Handler e -> Eff (e : es) a -> Eff es a
runHandler Handler e
e Eff (e : es) a
m = forall (es :: [Effect]) a. (Env es -> IO a) -> Eff es a
unsafeEff forall a b. (a -> b) -> a -> b
$ \Env es
es0 -> do
forall a b c. IO a -> (a -> IO b) -> (a -> IO c) -> IO c
E.bracket (forall (e :: Effect) (es :: [Effect]).
EffectRep (DispatchOf e) e
-> Relinker (EffectRep (DispatchOf e)) e
-> Env es
-> IO (Env (e : es))
consEnv Handler e
e forall (e :: Effect). Relinker Handler e
relinkHandler Env es
es0)
forall (e :: Effect) (es :: [Effect]). Env (e : es) -> IO ()
unconsEnv
(\Env (e : es)
es -> 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 = forall (es :: [Effect]) a. (Env es -> IO a) -> Eff es a
unsafeEff forall a b. (a -> b) -> a -> b
$ \Env es
es -> do
Handler Env es
handlerEs EffectHandler e es
handle <- forall (e :: Effect) (es :: [Effect]).
(e :> es) =>
Env es -> IO (EffectRep (DispatchOf e) e)
getEnv Env es
es
forall (es :: [Effect]) a. Eff es a -> Env es -> IO a
unEff (EffectHandler e es
handle (forall (localEs :: [Effect]) (handlerEs :: [Effect]).
Env localEs -> LocalEnv localEs handlerEs
LocalEnv Env es
es) e (Eff es) a
op) Env es
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
:: (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.
(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 = forall (es :: [Effect]) a. (Env es -> IO a) -> Eff es a
unsafeEff forall a b. (a -> b) -> a -> b
$ \Env es
es0 -> do
forall a b c. IO a -> (a -> IO b) -> (a -> IO c) -> IO c
E.bracket (forall (e :: Effect) (es :: [Effect]).
EffectRep (DispatchOf e) e
-> Relinker (EffectRep (DispatchOf e)) e
-> Env es
-> IO (Env (e : es))
consEnv StaticRep e
e0 forall (rep :: Effect -> Type) (e :: Effect). Relinker rep e
dummyRelinker Env es
es0)
forall (e :: Effect) (es :: [Effect]). Env (e : es) -> IO ()
unconsEnv
(\Env (e : es)
es -> (,) forall (f :: Type -> Type) a b. Functor f => (a -> b) -> f a -> f b
<$> forall (es :: [Effect]) a. Eff es a -> Env es -> IO a
unEff Eff (e : es) a
m Env (e : es)
es forall (f :: Type -> Type) a b.
Applicative f =>
f (a -> b) -> f a -> f b
<*> forall (e :: Effect) (es :: [Effect]).
(e :> es) =>
Env es -> IO (EffectRep (DispatchOf e) e)
getEnv Env (e : es)
es)
evalStaticRep
:: (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.
(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 = forall (es :: [Effect]) a. (Env es -> IO a) -> Eff es a
unsafeEff forall a b. (a -> b) -> a -> b
$ \Env es
es0 -> do
forall a b c. IO a -> (a -> IO b) -> (a -> IO c) -> IO c
E.bracket (forall (e :: Effect) (es :: [Effect]).
EffectRep (DispatchOf e) e
-> Relinker (EffectRep (DispatchOf e)) e
-> Env es
-> IO (Env (e : es))
consEnv StaticRep e
e forall (rep :: Effect -> Type) (e :: Effect). Relinker rep e
dummyRelinker Env es
es0)
forall (e :: Effect) (es :: [Effect]). Env (e : es) -> IO ()
unconsEnv
(\Env (e : es)
es -> forall (es :: [Effect]) a. Eff es a -> Env es -> IO a
unEff Eff (e : es) a
m Env (e : es)
es)
execStaticRep
:: (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.
(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 = forall (es :: [Effect]) a. (Env es -> IO a) -> Eff es a
unsafeEff forall a b. (a -> b) -> a -> b
$ \Env es
es0 -> do
forall a b c. IO a -> (a -> IO b) -> (a -> IO c) -> IO c
E.bracket (forall (e :: Effect) (es :: [Effect]).
EffectRep (DispatchOf e) e
-> Relinker (EffectRep (DispatchOf e)) e
-> Env es
-> IO (Env (e : es))
consEnv StaticRep e
e0 forall (rep :: Effect -> Type) (e :: Effect). Relinker rep e
dummyRelinker Env es
es0)
forall (e :: Effect) (es :: [Effect]). Env (e : es) -> IO ()
unconsEnv
(\Env (e : es)
es -> forall (es :: [Effect]) a. Eff es a -> Env es -> IO a
unEff Eff (e : es) a
m Env (e : es)
es forall (f :: Type -> Type) a b. Applicative f => f a -> f b -> f b
*> forall (e :: Effect) (es :: [Effect]).
(e :> es) =>
Env es -> IO (EffectRep (DispatchOf e) e)
getEnv Env (e : es)
es)
getStaticRep :: (DispatchOf e ~ Static sideEffects, e :> es) => Eff es (StaticRep e)
getStaticRep :: forall (e :: Effect) (sideEffects :: SideEffects) (es :: [Effect]).
(DispatchOf e ~ 'Static sideEffects, e :> es) =>
Eff es (StaticRep e)
getStaticRep = forall (es :: [Effect]) a. (Env es -> IO a) -> Eff es a
unsafeEff forall a b. (a -> b) -> a -> b
$ \Env es
es -> forall (e :: Effect) (es :: [Effect]).
(e :> es) =>
Env es -> IO (EffectRep (DispatchOf e) e)
getEnv Env es
es
putStaticRep :: (DispatchOf e ~ Static sideEffects, e :> es) => StaticRep e -> Eff es ()
putStaticRep :: forall (e :: Effect) (sideEffects :: SideEffects) (es :: [Effect]).
(DispatchOf e ~ 'Static sideEffects, e :> es) =>
StaticRep e -> Eff es ()
putStaticRep StaticRep e
s = forall (es :: [Effect]) a. (Env es -> IO a) -> Eff es a
unsafeEff forall a b. (a -> b) -> a -> b
$ \Env es
es -> forall (e :: Effect) (es :: [Effect]).
(e :> es) =>
Env es -> EffectRep (DispatchOf e) e -> IO ()
putEnv Env es
es StaticRep e
s
stateStaticRep
:: (DispatchOf e ~ Static sideEffects, e :> es)
=> (StaticRep e -> (a, StaticRep e))
-> Eff es a
stateStaticRep :: forall (e :: Effect) (sideEffects :: SideEffects) (es :: [Effect])
a.
(DispatchOf e ~ 'Static sideEffects, e :> es) =>
(StaticRep e -> (a, StaticRep e)) -> Eff es a
stateStaticRep StaticRep e -> (a, StaticRep e)
f = forall (es :: [Effect]) a. (Env es -> IO a) -> Eff es a
unsafeEff forall a b. (a -> b) -> a -> b
$ \Env es
es -> forall (e :: Effect) (es :: [Effect]) a.
(e :> es) =>
Env es
-> (EffectRep (DispatchOf e) e
-> IO (a, EffectRep (DispatchOf e) e))
-> IO a
stateEnv Env es
es (forall (f :: Type -> Type) a. Applicative f => a -> f a
pure forall b c a. (b -> c) -> (a -> b) -> a -> c
. StaticRep e -> (a, StaticRep e)
f)
stateStaticRepM
:: (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.
(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 = forall (es :: [Effect]) a. (Env es -> IO a) -> Eff es a
unsafeEff forall a b. (a -> b) -> a -> b
$ \Env es
es -> forall b. ((forall a. IO a -> IO a) -> IO b) -> IO b
E.mask forall a b. (a -> b) -> a -> b
$ \forall a. IO a -> IO a
unmask -> do
forall (e :: Effect) (es :: [Effect]) a.
(e :> es) =>
Env es
-> (EffectRep (DispatchOf e) e
-> IO (a, EffectRep (DispatchOf e) e))
-> IO a
stateEnv Env es
es forall a b. (a -> b) -> a -> b
$ forall a. IO a -> IO a
unmask forall b c a. (b -> c) -> (a -> b) -> a -> c
. (forall (es :: [Effect]) a. Eff es a -> Env es -> IO a
`unEff` Env es
es) forall b c a. (b -> c) -> (a -> b) -> a -> c
. StaticRep e -> Eff es (a, StaticRep e)
f
localStaticRep
:: (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.
(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 = forall (es :: [Effect]) a. (Env es -> IO a) -> Eff es a
unsafeEff forall a b. (a -> b) -> a -> b
$ \Env es
es -> do
forall a b c. IO a -> (a -> IO b) -> (a -> IO c) -> IO c
E.bracket (forall (e :: Effect) (es :: [Effect]) a.
(e :> es) =>
Env es
-> (EffectRep (DispatchOf e) e
-> IO (a, EffectRep (DispatchOf e) e))
-> IO a
stateEnv Env es
es forall a b. (a -> b) -> a -> b
$ \EffectRep (DispatchOf e) e
s -> forall (f :: Type -> Type) a. Applicative f => a -> f a
pure (EffectRep (DispatchOf e) e
s, StaticRep e -> StaticRep e
f EffectRep (DispatchOf e) e
s))
(\StaticRep e
s -> forall (e :: Effect) (es :: [Effect]).
(e :> es) =>
Env es -> EffectRep (DispatchOf e) e -> IO ()
putEnv Env es
es StaticRep e
s)
(\StaticRep e
_ -> forall (es :: [Effect]) a. Eff es a -> Env es -> IO a
unEff Eff es a
m Env es
es)