{-# LANGUAGE RankNTypes #-}
{-# LANGUAGE TypeOperators #-}
{-# LANGUAGE DataKinds #-}
{-# LANGUAGE TypeFamilies #-}
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE MultiParamTypeClasses #-}
module Effectful.ST
(
STE
, runSTE
, steAsPrim
, steAsIOE
, primToSTE
, stToSTE
, stToSTE'
, ioToSTE
, primToIOE
, stToIOE
, stToIOE'
) where
import Control.Monad.ST ( RealWorld, ST )
import qualified Control.Monad.ST.Lazy as L
import Unsafe.Coerce ( unsafeCoerce )
import GHC.IO ( IO(IO) )
import Effectful
( type (:>), Effect, Dispatch(Static), DispatchOf, Eff, IOE )
import Effectful.Dispatch.Static
( evalStaticRep,
unsafeEff_,
SideEffects(NoSideEffects),
StaticRep )
import Effectful.Prim ( Prim )
import Effectful.Internal.Effect ( type (:>)(..) )
import Control.Monad.Primitive
( PrimBase(..), PrimMonad(PrimState) )
data STE s :: Effect
type instance DispatchOf (STE s) = Static NoSideEffects
data instance StaticRep (STE s) = STERep
instance {-# INCOHERENT #-} s1 ~ s2 => STE s1 :> (STE s2 : es) where
reifyIndex :: Int
reifyIndex = Int
0
runSTE :: (forall s. Eff (STE s : es) a) -> Eff es a
runSTE :: forall (es :: [(* -> *) -> * -> *]) a.
(forall s. Eff (STE s : es) a) -> Eff es a
runSTE forall s. Eff (STE s : es) a
eff = forall (e :: (* -> *) -> * -> *) (sideEffects :: SideEffects)
(es :: [(* -> *) -> * -> *]) a.
(DispatchOf e ~ 'Static sideEffects, MaybeIOE sideEffects es) =>
StaticRep e -> Eff (e : es) a -> Eff es a
evalStaticRep forall s. StaticRep (STE s)
STERep forall s. Eff (STE s : es) a
eff
steAsPrim :: Prim :> es => Eff (STE (PrimState (Eff es)) : es) a -> Eff es a
steAsPrim :: forall (es :: [(* -> *) -> * -> *]) a.
(Prim :> es) =>
Eff (STE (PrimState (Eff es)) : es) a -> Eff es a
steAsPrim = forall (e :: (* -> *) -> * -> *) (sideEffects :: SideEffects)
(es :: [(* -> *) -> * -> *]) a.
(DispatchOf e ~ 'Static sideEffects, MaybeIOE sideEffects es) =>
StaticRep e -> Eff (e : es) a -> Eff es a
evalStaticRep forall s. StaticRep (STE s)
STERep
steAsIOE :: IOE :> es => Eff (STE RealWorld : es) a -> Eff es a
steAsIOE :: forall (es :: [(* -> *) -> * -> *]) a.
(IOE :> es) =>
Eff (STE RealWorld : es) a -> Eff es a
steAsIOE = forall (e :: (* -> *) -> * -> *) (sideEffects :: SideEffects)
(es :: [(* -> *) -> * -> *]) a.
(DispatchOf e ~ 'Static sideEffects, MaybeIOE sideEffects es) =>
StaticRep e -> Eff (e : es) a -> Eff es a
evalStaticRep forall s. StaticRep (STE s)
STERep
primToSTE
:: (PrimBase m, STE s :> es, PrimState m ~ s)
=> m a -> Eff es a
primToSTE :: forall (m :: * -> *) s (es :: [(* -> *) -> * -> *]) a.
(PrimBase m, STE s :> es, PrimState m ~ s) =>
m a -> Eff es a
primToSTE = forall a (es :: [(* -> *) -> * -> *]). 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 forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall (m :: * -> *) a.
PrimBase m =>
m a -> State# (PrimState m) -> (# State# (PrimState m), a #)
internal
stToSTE :: (STE s :> es) => ST s a -> Eff es a
stToSTE :: forall s (es :: [(* -> *) -> * -> *]) a.
(STE s :> es) =>
ST s a -> Eff es a
stToSTE = forall (m :: * -> *) s (es :: [(* -> *) -> * -> *]) a.
(PrimBase m, STE s :> es, PrimState m ~ s) =>
m a -> Eff es a
primToSTE
stToSTE' :: (STE s :> es) => L.ST s a -> Eff es a
stToSTE' :: forall s (es :: [(* -> *) -> * -> *]) a.
(STE s :> es) =>
ST s a -> Eff es a
stToSTE' = forall (m :: * -> *) s (es :: [(* -> *) -> * -> *]) a.
(PrimBase m, STE s :> es, PrimState m ~ s) =>
m a -> Eff es a
primToSTE
ioToSTE :: (STE RealWorld :> es) => IO a -> Eff es a
ioToSTE :: forall (es :: [(* -> *) -> * -> *]) a.
(STE RealWorld :> es) =>
IO a -> Eff es a
ioToSTE = forall (m :: * -> *) s (es :: [(* -> *) -> * -> *]) a.
(PrimBase m, STE s :> es, PrimState m ~ s) =>
m a -> Eff es a
primToSTE
primToIOE
:: (PrimBase m, IOE :> es, PrimState m ~ RealWorld)
=> m a -> Eff es a
primToIOE :: forall (m :: * -> *) (es :: [(* -> *) -> * -> *]) a.
(PrimBase m, IOE :> es, PrimState m ~ RealWorld) =>
m a -> Eff es a
primToIOE = forall a (es :: [(* -> *) -> * -> *]). 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 (m :: * -> *) a.
PrimBase m =>
m a -> State# (PrimState m) -> (# State# (PrimState m), a #)
internal
stToIOE :: (IOE :> es) => ST RealWorld a -> Eff es a
stToIOE :: forall (es :: [(* -> *) -> * -> *]) a.
(IOE :> es) =>
ST RealWorld a -> Eff es a
stToIOE = forall (m :: * -> *) (es :: [(* -> *) -> * -> *]) a.
(PrimBase m, IOE :> es, PrimState m ~ RealWorld) =>
m a -> Eff es a
primToIOE
stToIOE' :: (IOE :> es) => L.ST RealWorld a -> Eff es a
stToIOE' :: forall (es :: [(* -> *) -> * -> *]) a.
(IOE :> es) =>
ST RealWorld a -> Eff es a
stToIOE' = forall (m :: * -> *) (es :: [(* -> *) -> * -> *]) a.
(PrimBase m, IOE :> es, PrimState m ~ RealWorld) =>
m a -> Eff es a
primToIOE