module Control.Effect.Intercept
  ( -- * Effects
    Intercept(..)
  , InterceptCont(..)
  , InterceptionMode(..)

    -- * Actions
  , intercept
  , interceptCont
  , interceptCont1

    -- * Interpretations
  , runInterceptCont
  , runInterceptR

    -- * Interpretations for other effects
  , runStateStepped
  , runTellStepped
  , runTellListStepped
  , runListenStepped

    -- * Threading constraints
  , SteppedThreads

    -- * Carriers
  , InterceptContC
  , InterceptRC
  , SteppedC
  , ListenSteppedC
  ) where

import Control.Effect
import Control.Effect.Stepped
import Control.Effect.Internal.Intercept

-- | Intercept all uses of an effect within a region.
intercept :: Eff (Intercept e) m => (forall x. e m x -> m x) -> m a -> m a
intercept :: (forall x. e m x -> m x) -> m a -> m a
intercept forall x. e m x -> m x
h m a
m = Intercept e m a -> m a
forall (e :: Effect) (m :: * -> *) a.
(Member e (Derivs m), Carrier m) =>
e m a -> m a
send ((forall x. e m x -> m x) -> m a -> Intercept e m a
forall (z :: * -> *) (m :: * -> *) (e :: Effect) a.
Coercible z m =>
(forall x. e z x -> m x) -> m a -> Intercept e m a
Intercept forall x. e m x -> m x
h m a
m)
{-# INLINE intercept #-}

-- | Intercept all uses of an effect within a region -- and at each use-site,
-- capture the continuation of the argument computation, and also allow for
-- early abortion (by not invoking the continuation).
interceptCont :: Eff (InterceptCont e) m
              => (forall x. (x -> m a) -> e m x -> m a)
              -> m a -> m a
interceptCont :: (forall x. (x -> m a) -> e m x -> m a) -> m a -> m a
interceptCont forall x. (x -> m a) -> e m x -> m a
h m a
m = InterceptCont e m a -> m a
forall (e :: Effect) (m :: * -> *) a.
(Member e (Derivs m), Carrier m) =>
e m a -> m a
send (InterceptionMode
-> (forall x. (x -> m a) -> e m x -> m a)
-> m a
-> InterceptCont e m a
forall (z :: * -> *) (m :: * -> *) a (e :: Effect).
Coercible z m =>
InterceptionMode
-> (forall x. (x -> m a) -> e z x -> m a)
-> m a
-> InterceptCont e m a
InterceptCont InterceptionMode
InterceptAll forall x. (x -> m a) -> e m x -> m a
h m a
m)
{-# INLINE interceptCont #-}

-- | Intercept only the /first/ use of an effect within a region --
-- and at that use-site, capture the continuation of the argument computation,
-- and also allow for early abortion (by not invoking the continuation).
interceptCont1 :: Eff (InterceptCont e) m
               => (forall x. (x -> m a) -> e m x -> m a)
               -> m a -> m a
interceptCont1 :: (forall x. (x -> m a) -> e m x -> m a) -> m a -> m a
interceptCont1 forall x. (x -> m a) -> e m x -> m a
h m a
m = InterceptCont e m a -> m a
forall (e :: Effect) (m :: * -> *) a.
(Member e (Derivs m), Carrier m) =>
e m a -> m a
send (InterceptionMode
-> (forall x. (x -> m a) -> e m x -> m a)
-> m a
-> InterceptCont e m a
forall (z :: * -> *) (m :: * -> *) a (e :: Effect).
Coercible z m =>
InterceptionMode
-> (forall x. (x -> m a) -> e z x -> m a)
-> m a
-> InterceptCont e m a
InterceptCont InterceptionMode
InterceptOne forall x. (x -> m a) -> e m x -> m a
h m a
m)
{-# INLINE interceptCont1 #-}