{-# LANGUAGE AllowAmbiguousTypes #-}
{-# OPTIONS_HADDOCK not-home #-}
module Control.Effect.Internal.Union where
import Data.Coerce
import Data.Kind (Constraint)
import Control.Monad.Trans
import Control.Monad.Trans.Reader (ReaderT)
import Control.Effect.Internal.Membership
import Control.Effect.Internal.Utils
type Effect = (Type -> Type) -> Type -> Type
data Union (r :: [Effect]) m a where
Union :: Coercible z m => ElemOf e r -> e z a -> Union r m a
type Algebra r m = forall x. Union r m x -> m x
type Algebra' r m a = Union r m a -> m a
class ( forall m n x. Coercible m n => Coercible (e m x) (e n x) )
=> RepresentationalEff (e :: Effect)
instance ( forall m n x. Coercible m n => Coercible (e m x) (e n x) )
=> RepresentationalEff (e :: Effect)
decomp :: RepresentationalEff e
=> Union (e ': r) m a
-> Either (Union r m a) (e m a)
decomp :: Union (e : r) m a -> Either (Union r m a) (e m a)
decomp (Union ElemOf e (e : r)
Here e z a
e) = e m a -> Either (Union r m a) (e m a)
forall a b. b -> Either a b
Right (e z a -> e m a
coerce e z a
e)
decomp (Union (There ElemOf e r
pr) e z a
e) = Union r m a -> Either (Union r m a) (e m a)
forall a b. a -> Either a b
Left (ElemOf e r -> e z a -> Union r m a
forall (z :: * -> *) (m :: * -> *) (e :: Effect) (r :: [Effect]) a.
Coercible z m =>
ElemOf e r -> e z a -> Union r m a
Union ElemOf e r
pr e z a
e)
{-# INLINE decomp #-}
extract :: RepresentationalEff e
=> Union '[e] m a
-> e m a
(Union ElemOf e '[e]
Here e z a
e) = e z a -> e m a
coerce e z a
e
extract (Union (There ElemOf e r
pr) e z a
_) = ElemOf e '[] -> e m a
forall a (e :: a) b. ElemOf e '[] -> b
absurdMember ElemOf e r
ElemOf e '[]
pr
{-# INLINE extract #-}
weaken :: Union r m a -> Union (e ': r) m a
weaken :: Union r m a -> Union (e : r) m a
weaken (Union ElemOf e r
pr e z a
e) = ElemOf e (e : r) -> e z a -> Union (e : r) m a
forall (z :: * -> *) (m :: * -> *) (e :: Effect) (r :: [Effect]) a.
Coercible z m =>
ElemOf e r -> e z a -> Union r m a
Union (ElemOf e r -> ElemOf e (e : r)
forall a (e :: a) (r :: [a]) (_e :: a).
ElemOf e r -> ElemOf e (_e : r)
There ElemOf e r
pr) e z a
e
{-# INLINE weaken #-}
absurdU :: Union '[] m a -> b
absurdU :: Union '[] m a -> b
absurdU (Union ElemOf e '[]
pr e z a
_) = case ElemOf e '[]
pr of {}
{-# INLINE absurdU #-}
weakenAlg :: Algebra' (e ': r) m a -> Algebra' r m a
weakenAlg :: Algebra' (e : r) m a -> Algebra' r m a
weakenAlg Algebra' (e : r) m a
alg Union r m a
u = Algebra' (e : r) m a
alg (Union r m a -> Union (e : r) m a
forall (r :: [Effect]) (m :: * -> *) a (e :: Effect).
Union r m a -> Union (e : r) m a
weaken Union r m a
u)
{-# INLINE weakenAlg #-}
powerAlg :: forall e r m a
. RepresentationalEff e
=> Algebra' r m a
-> (e m a -> m a)
-> Algebra' (e ': r) m a
powerAlg :: Algebra' r m a -> (e m a -> m a) -> Algebra' (e : r) m a
powerAlg Algebra' r m a
alg e m a -> m a
h = Algebra' r m a
-> (forall (z :: * -> *). Coercible z m => e z a -> m a)
-> Algebra' (e : r) m a
forall (e :: Effect) (r :: [Effect]) (m :: * -> *) a.
Algebra' r m a
-> (forall (z :: * -> *). Coercible z m => e z a -> m a)
-> Algebra' (e : r) m a
powerAlg' Algebra' r m a
alg (e m a -> m a
h (e m a -> m a) -> (e z a -> e m a) -> e z a -> m a
forall b a c. Coercible b a => (b -> c) -> (a -> b) -> a -> c
.# e z a -> e m a
coerce)
{-# INLINE powerAlg #-}
powerAlg' :: forall e r m a
. Algebra' r m a
-> (forall z. Coercible z m => e z a -> m a)
-> Algebra' (e ': r) m a
powerAlg' :: Algebra' r m a
-> (forall (z :: * -> *). Coercible z m => e z a -> m a)
-> Algebra' (e : r) m a
powerAlg' Algebra' r m a
_ forall (z :: * -> *). Coercible z m => e z a -> m a
h (Union ElemOf e (e : r)
Here e z a
e) = e z a -> m a
forall (z :: * -> *). Coercible z m => e z a -> m a
h e z a
e z a
e
powerAlg' Algebra' r m a
alg forall (z :: * -> *). Coercible z m => e z a -> m a
_ (Union (There ElemOf e r
pr) e z a
e) = Algebra' r m a
alg (ElemOf e r -> e z a -> Union r m a
forall (z :: * -> *) (m :: * -> *) (e :: Effect) (r :: [Effect]) a.
Coercible z m =>
ElemOf e r -> e z a -> Union r m a
Union ElemOf e r
pr e z a
e)
{-# INLINEABLE powerAlg' #-}
addPrim :: forall e r p m z a
. Monad z
=> Reformulation' r p m z a
-> Reformulation' (e ': r) (e ': p) m z a
addPrim :: Reformulation' r p m z a -> Reformulation' (e : r) (e : p) m z a
addPrim Reformulation' r p m z a
reform forall x. m x -> z x
n Algebra (e : p) z
alg = Algebra' r z a
-> (forall (z :: * -> *). Coercible z z => e z a -> z a)
-> Algebra' (e : r) z a
forall (e :: Effect) (r :: [Effect]) (m :: * -> *) a.
Algebra' r m a
-> (forall (z :: * -> *). Coercible z m => e z a -> m a)
-> Algebra' (e : r) m a
powerAlg' (Reformulation' r p m z a
reform forall x. m x -> z x
n (Algebra' (e : p) z x -> Algebra' p z x
forall (e :: Effect) (r :: [Effect]) (m :: * -> *) a.
Algebra' (e : r) m a -> Algebra' r m a
weakenAlg Algebra' (e : p) z x
Algebra (e : p) z
alg)) (Union (e : p) z a -> z a
Algebra (e : p) z
alg (Union (e : p) z a -> z a)
-> (e z a -> Union (e : p) z a) -> e z a -> z a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ElemOf e (e : p) -> e z a -> Union (e : p) z a
forall (z :: * -> *) (m :: * -> *) (e :: Effect) (r :: [Effect]) a.
Coercible z m =>
ElemOf e r -> e z a -> Union r m a
Union ElemOf e (e : p)
forall a (e :: a) (r :: [a]). ElemOf e (e : r)
Here)
{-# INLINE addPrim #-}
liftReform
:: (MonadTrans t, Monad m)
=> Reformulation' r p m z a
-> Reformulation' r p (t m) z a
liftReform :: Reformulation' r p m z a -> Reformulation' r p (t m) z a
liftReform Reformulation' r p m z a
reform = \forall x. t m x -> z x
n -> Reformulation' r p m z a
reform (t m x -> z x
forall x. t m x -> z x
n (t m x -> z x) -> (m x -> t m x) -> m x -> z x
forall b c a. (b -> c) -> (a -> b) -> a -> c
. m x -> t m x
forall (t :: Effect) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift)
{-# INLINE liftReform #-}
coerceReform :: Coercible m n
=> Reformulation' r p m z a
-> Reformulation' r p n z a
coerceReform :: Reformulation' r p m z a -> Reformulation' r p n z a
coerceReform Reformulation' r p m z a
reform forall x. n x -> z x
n Algebra p z
alg = Algebra' r z a -> Algebra' r z a
coerce (Reformulation' r p m z a
reform (n x -> z x
forall x. n x -> z x
n (n x -> z x) -> (m x -> n x) -> m x -> z x
forall b a c. Coercible b a => (b -> c) -> (a -> b) -> a -> c
.# m x -> n x
coerce) Algebra p z
alg)
{-# INLINE coerceReform #-}
weakenReform :: Reformulation' (e ': r) p m z a
-> Reformulation' r p m z a
weakenReform :: Reformulation' (e : r) p m z a -> Reformulation' r p m z a
weakenReform Reformulation' (e : r) p m z a
reform forall x. m x -> z x
n Algebra p z
alg = Algebra' (e : r) z a -> Algebra' r z a
forall (e :: Effect) (r :: [Effect]) (m :: * -> *) a.
Algebra' (e : r) m a -> Algebra' r m a
weakenAlg (Reformulation' (e : r) p m z a
reform forall x. m x -> z x
n Algebra p z
alg)
{-# INLINE weakenReform #-}
type Reformulation' r p m z a
= (forall x. m x -> z x)
-> Algebra p z
-> Algebra' r z a
type Reformulation r p m
= forall z
. Monad z
=> (forall x. m x -> z x)
-> Algebra p z
-> Algebra r z
class RepresentationalEff e => ThreadsEff t e where
threadEff :: Monad m
=> (forall x. e m x -> m x)
-> e (t m) a
-> t m a
class Threads t p where
thread :: Monad m
=> Algebra p m
-> Algebra p (t m)
instance Threads t '[] where
thread :: Algebra '[] m -> Algebra '[] (t m)
thread Algebra '[] m
_ = Union '[] (t m) x -> t m x
forall (m :: * -> *) a b. Union '[] m a -> b
absurdU
{-# INLINE thread #-}
instance (ThreadsEff t e, Threads t p) => Threads t (e ': p) where
thread :: Algebra (e : p) m -> Algebra (e : p) (t m)
thread Algebra (e : p) m
alg = Algebra' p (t m) x
-> (e (t m) x -> t m x) -> Algebra' (e : p) (t m) x
forall (e :: Effect) (r :: [Effect]) (m :: * -> *) a.
RepresentationalEff e =>
Algebra' r m a -> (e m a -> m a) -> Algebra' (e : r) m a
powerAlg (Algebra p m -> Algebra p (t m)
forall (t :: Effect) (p :: [Effect]) (m :: * -> *).
(Threads t p, Monad m) =>
Algebra p m -> Algebra p (t m)
thread (Algebra' (e : p) m x -> Algebra' p m x
forall (e :: Effect) (r :: [Effect]) (m :: * -> *) a.
Algebra' (e : r) m a -> Algebra' r m a
weakenAlg Algebra' (e : p) m x
Algebra (e : p) m
alg)) ((forall x. e m x -> m x) -> e (t m) x -> t m x
forall (t :: Effect) (e :: Effect) (m :: * -> *) a.
(ThreadsEff t e, Monad m) =>
(forall x. e m x -> m x) -> e (t m) a -> t m a
threadEff (Union (e : p) m x -> m x
Algebra (e : p) m
alg (Union (e : p) m x -> m x)
-> (e m x -> Union (e : p) m x) -> e m x -> m x
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ElemOf e (e : p) -> e m x -> Union (e : p) m x
forall (z :: * -> *) (m :: * -> *) (e :: Effect) (r :: [Effect]) a.
Coercible z m =>
ElemOf e r -> e z a -> Union r m a
Union ElemOf e (e : p)
forall a (e :: a) (r :: [a]). ElemOf e (e : r)
Here))
{-# INLINEABLE thread #-}
inj :: Member e r => e m a -> Union r m a
inj :: e m a -> Union r m a
inj = ElemOf e r -> e m a -> Union r m a
forall (z :: * -> *) (m :: * -> *) (e :: Effect) (r :: [Effect]) a.
Coercible z m =>
ElemOf e r -> e z a -> Union r m a
Union ElemOf e r
forall k (e :: k) (r :: [k]). Member e r => ElemOf e r
membership
{-# INLINE inj #-}
class (forall i. Threads (ReaderT i) p) => ReaderThreads p
instance (forall i. Threads (ReaderT i) p) => ReaderThreads p
coerceEff :: forall n m e a
. (Coercible n m, RepresentationalEff e)
=> e m a
-> e n a
coerceEff :: e m a -> e n a
coerceEff = e m a -> e n a
coerce
{-# INLINE coerceEff #-}
coerceAlg :: forall n m e a b
. (Coercible n m, RepresentationalEff e)
=> (e m a -> m b)
-> e n a -> n b
coerceAlg :: (e m a -> m b) -> e n a -> n b
coerceAlg = (e m a -> m b) -> e n a -> n b
coerce
{-# INLINE coerceAlg #-}
data Bundle :: [Effect] -> Effect
type family Append l r where
Append '[] r = r
Append (x ': l) r = x ': (Append l r)
type family FlattenBundles (e :: [Effect]) :: [Effect] where
FlattenBundles '[] = '[]
FlattenBundles (Bundle bs ': es) = Append (FlattenBundles bs) (FlattenBundles es)
FlattenBundles (e ': es) = e ': FlattenBundles es
type family Members (es :: [Effect]) (r :: [Effect]) :: Constraint where
Members '[] r = ()
Members (e ': es) r = (Member e r, Members es r)
type EffMembers (xs :: [Effect]) (r :: [Effect]) = Members (FlattenBundles xs) r