{-# LANGUAGE AllowAmbiguousTypes #-}
module Polysemy.Bundle
(
Bundle (..)
, sendBundle
, injBundle
, runBundle
, subsumeBundle
, KnownList
) where
import Polysemy
import Polysemy.Internal
import Polysemy.Internal.Bundle
import Polysemy.Internal.Union
data Bundle r m a where
Bundle :: ElemOf e r -> e m a -> Bundle r m a
injBundle :: forall e r m a. Member e r => e m a -> Bundle r m a
injBundle = Bundle membership
{-# INLINE injBundle #-}
sendBundle
:: forall e r' r a
. (Member e r', Member (Bundle r') r)
=> Sem (e ': r) a
-> Sem r a
sendBundle = hoistSem $ \u -> case decomp u of
Right (Weaving e s wv ex ins) ->
injWeaving $
Weaving (Bundle (membership @e @r') e) s (sendBundle @e @r' . wv) ex ins
Left g -> hoist (sendBundle @e @r') g
{-# INLINE sendBundle #-}
runBundle
:: forall r' r a
. KnownList r'
=> Sem (Bundle r' ': r) a
-> Sem (Append r' r) a
runBundle = hoistSem $ \u -> hoist runBundle $ case decomp u of
Right (Weaving (Bundle pr e) s wv ex ins) ->
Union (extendMembership @_ @r pr) $ Weaving e s wv ex ins
Left g -> weakenList @r' @r g
{-# INLINE runBundle #-}
subsumeBundle
:: forall r' r a
. Members r' r
=> Sem (Bundle r' ': r) a
-> Sem r a
subsumeBundle = hoistSem $ \u -> hoist subsumeBundle $ case decomp u of
Right (Weaving (Bundle pr e) s wv ex ins) ->
Union (subsumeMembership pr) (Weaving e s wv ex ins)
Left g -> g
{-# INLINE subsumeBundle #-}