{-# LANGUAGE BlockArguments, DerivingVia #-}
module Control.Effect.Writer
  ( -- * Effects
    Tell(..)
  , Listen(..)
  , Pass(..)
  , Writer

  -- * Actions
  , tell
  , listen
  , pass
  , censor

  -- * Interpretations for 'Tell'
  , runTell

  , runTellLazy

  , runTellList

  , runTellListLazy

  , tellToIO
  , runTellIORef
  , runTellTVar

  , runTellAction

  , tellIntoEndoTell
  , tellToTell
  , tellIntoTell

  , ignoreTell

  -- * Simple variants of interpretations for 'Tell'
  , tellToIOSimple
  , runTellIORefSimple
  , runTellTVarSimple

  , runTellActionSimple

  , tellToTellSimple
  , tellIntoTellSimple

  -- * Interpretations for 'Tell' + 'Listen'
  , runListen

  , runListenLazy

  , listenToIO
  , runListenTVar

  , listenIntoEndoListen

  -- * Interpretations for 'Writer' ('Tell' + 'Listen' + 'Pass')
  , runWriter

  , runWriterLazy

  , writerToIO
  , runWriterTVar

  , writerToBracket
  , writerToBracketTVar

  , writerIntoEndoWriter

    -- * Other utilities
  , fromEndoWriter

    -- * Threading constraints
  , WriterThreads
  , WriterLazyThreads

    -- * MonadMask
  , C.MonadMask

    -- * Carriers
  , TellC
  , TellLazyC
  , TellListC
  , TellListLazyC
  , TellIntoEndoTellC
  , IgnoreTellC
  , ListenC
  , ListenLazyC
  , ListenTVarC
  , ListenIntoEndoListenC
  , WriterC
  , WriterLazyC
  , WriterTVarC
  , WriterToBracketC
  , WriterIntoEndoWriterC
  ) where

import Data.Bifunctor
import Data.Semigroup
import Data.Tuple (swap)
import Data.IORef

import Control.Concurrent.STM

import Control.Monad

import Control.Effect
import Control.Effect.Reader
import Control.Effect.Bracket
import Control.Effect.Type.ListenPrim
import Control.Effect.Type.WriterPrim

import Control.Effect.Carrier
import Control.Effect.Internal.Writer

import qualified Control.Monad.Catch as C

import qualified Control.Monad.Trans.Writer.CPS as W
import qualified Control.Monad.Trans.Writer.Lazy as LW

-- For coercion purposes
import Control.Effect.Internal.Utils
import Control.Effect.Carrier.Internal.Interpret
import Control.Effect.Carrier.Internal.Compose
import Control.Effect.Carrier.Internal.Intro
import Control.Monad.Trans.Identity

-- | A pseudo-effect for connected @'Tell' o@, @'Listen' o@ and @'Pass' o@ effects.
--
-- @'Writer'@ should only ever be used inside of 'Eff' and 'Effs'
-- constraints. It is not a real effect! See 'Bundle'.
type Writer o = Bundle '[Tell o, Listen o, Pass o]

tell :: Eff (Tell o) m => o -> m ()
tell :: o -> m ()
tell = Tell o m () -> m ()
forall (e :: Effect) (m :: * -> *) a.
(Member e (Derivs m), Carrier m) =>
e m a -> m a
send (Tell o m () -> m ()) -> (o -> Tell o m ()) -> o -> m ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. o -> Tell o m ()
forall o (m :: * -> *). o -> Tell o m ()
Tell
{-# INLINE tell #-}

listen :: Eff (Listen o) m => m a -> m (o, a)
listen :: m a -> m (o, a)
listen = Listen o m (o, a) -> m (o, a)
forall (e :: Effect) (m :: * -> *) a.
(Member e (Derivs m), Carrier m) =>
e m a -> m a
send (Listen o m (o, a) -> m (o, a))
-> (m a -> Listen o m (o, a)) -> m a -> m (o, a)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. m a -> Listen o m (o, a)
forall (m :: * -> *) a o. m a -> Listen o m (o, a)
Listen
{-# INLINE listen #-}

pass :: Eff (Pass o) m => m (o -> o, a) -> m a
pass :: m (o -> o, a) -> m a
pass = Pass o m a -> m a
forall (e :: Effect) (m :: * -> *) a.
(Member e (Derivs m), Carrier m) =>
e m a -> m a
send (Pass o m a -> m a)
-> (m (o -> o, a) -> Pass o m a) -> m (o -> o, a) -> m a
forall b a c. Coercible b a => (b -> c) -> (a -> b) -> a -> c
.# m (o -> o, a) -> Pass o m a
forall (m :: * -> *) o a. m (o -> o, a) -> Pass o m a
Pass
{-# INLINE pass #-}

censor :: Eff (Pass o) m => (o -> o) -> m a -> m a
censor :: (o -> o) -> m a -> m a
censor o -> o
f = m (o -> o, a) -> m a
forall o (m :: * -> *) a. Eff (Pass o) m => m (o -> o, a) -> m a
pass (m (o -> o, a) -> m a) -> (m a -> m (o -> o, a)) -> m a -> m a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (a -> (o -> o, a)) -> m a -> m (o -> o, a)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap ((,) o -> o
f)
{-# INLINE censor #-}


data TellListH

type TellListC o = CompositionC
 '[ ReinterpretC TellListH (Tell o) '[Tell (Dual [o])]
  , TellC (Dual [o])
  ]

instance Eff (Tell (Dual [o])) m
      => Handler TellListH (Tell o) m where
  effHandler :: Tell o (Effly z) x -> Effly z x
effHandler (Tell o
o) = Dual [o] -> Effly z ()
forall o (m :: * -> *). Eff (Tell o) m => o -> m ()
tell ([o] -> Dual [o]
forall a. a -> Dual a
Dual [o
o])
  {-# INLINEABLE effHandler #-}

-- | Run a @'Tell' o@ effect by gathering the 'tell's into a list.
--
-- @'Derivs' ('TellListC' o m) = 'Tell' o ': 'Derivs' m@
--
-- @'Prims'  ('TellListC' o m) = 'Prims' m@
--
-- The resulting list is produced strictly. See 'runTellListLazy' for a lazy
-- variant.
runTellList :: forall o m a p
             . ( Carrier m
               , Threaders '[WriterThreads] m p
               )
            => TellListC o m a
            -> m ([o], a)
runTellList :: TellListC o m a -> m ([o], a)
runTellList =
     (((Dual [o], a) -> ([o], a)) -> m (Dual [o], a) -> m ([o], a)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (((Dual [o], a) -> ([o], a)) -> m (Dual [o], a) -> m ([o], a))
-> ((Dual [o] -> [o]) -> (Dual [o], a) -> ([o], a))
-> (Dual [o] -> [o])
-> m (Dual [o], a)
-> m ([o], a)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Dual [o] -> [o]) -> (Dual [o], a) -> ([o], a)
forall (p :: * -> * -> *) a b c.
Bifunctor p =>
(a -> b) -> p a c -> p b c
first) ([o] -> [o]
forall a. [a] -> [a]
reverse ([o] -> [o]) -> (Dual [o] -> [o]) -> Dual [o] -> [o]
forall b a c. Coercible b a => (b -> c) -> (a -> b) -> a -> c
.# Dual [o] -> [o]
forall a. Dual a -> a
getDual)
  (m (Dual [o], a) -> m ([o], a))
-> (TellC (Dual [o]) m a -> m (Dual [o], a))
-> TellC (Dual [o]) m a
-> m ([o], a)
forall b c a. (b -> c) -> (a -> b) -> a -> c
.  TellC (Dual [o]) m a -> m (Dual [o], a)
forall o (m :: * -> *) a (p :: [Effect]).
(Monoid o, Carrier m, Threaders '[WriterThreads] m p) =>
TellC o m a -> m (o, a)
runTell
  (TellC (Dual [o]) m a -> m ([o], a))
-> (ReinterpretC
      TellListH (Tell o) '[Tell (Dual [o])] (TellC (Dual [o]) m) a
    -> TellC (Dual [o]) m a)
-> ReinterpretC
     TellListH (Tell o) '[Tell (Dual [o])] (TellC (Dual [o]) m) a
-> m ([o], a)
forall b a c. Coercible b a => (b -> c) -> (a -> b) -> a -> c
.# ReinterpretC
  TellListH (Tell o) '[Tell (Dual [o])] (TellC (Dual [o]) m) a
-> TellC (Dual [o]) m a
forall h (e :: Effect) (new :: [Effect]) (m :: * -> *) a.
(Handler h e m, KnownList new, HeadEffs new m) =>
ReinterpretC h e new m a -> m a
reinterpretViaHandler
  (ReinterpretC
   TellListH (Tell o) '[Tell (Dual [o])] (TellC (Dual [o]) m) a
 -> m ([o], a))
-> (TellListC o m a
    -> ReinterpretC
         TellListH (Tell o) '[Tell (Dual [o])] (TellC (Dual [o]) m) a)
-> TellListC o m a
-> m ([o], a)
forall b a c. Coercible b a => (b -> c) -> (a -> b) -> a -> c
.# TellListC o m a
-> ReinterpretC
     TellListH (Tell o) '[Tell (Dual [o])] (TellC (Dual [o]) m) a
forall (ts :: [Effect]) (m :: * -> *) a.
CompositionC ts m a -> CompositionBaseM ts m a
runComposition
{-# INLINE runTellList #-}

data TellListLazyH

type TellListLazyC o = CompositionC
 '[ ReinterpretC TellListLazyH (Tell o) '[Tell (Endo [o])]
  , TellLazyC (Endo [o])
  ]

instance Eff (Tell (Endo [o])) m
      => Handler TellListLazyH (Tell o) m where
  effHandler :: Tell o (Effly z) x -> Effly z x
effHandler (Tell o
o) = Endo [o] -> Effly z ()
forall o (m :: * -> *). Eff (Tell o) m => o -> m ()
tell (([o] -> [o]) -> Endo [o]
forall a. (a -> a) -> Endo a
Endo (o
oo -> [o] -> [o]
forall a. a -> [a] -> [a]
:))
  {-# INLINEABLE effHandler #-}

-- | Run a @'Tell' o@ by gathering the 'tell's into a list.
--
-- @'Derivs' ('TellListLazyC' o m) = 'Tell' o ': 'Derivs' m@
--
-- @'Prims'  ('TellListLazyC' o m) = 'Prims' m@
--
-- This is a variant of 'runTellList' that produces the
-- final list lazily. __Use this only if you need__
-- __the laziness, as this would otherwise incur an unneccesary space leak.__
runTellListLazy :: forall o m a p
                 . ( Carrier m
                   , Threaders '[WriterLazyThreads] m p
                   )
                => TellListLazyC o m a
                -> m ([o], a)
runTellListLazy :: TellListLazyC o m a -> m ([o], a)
runTellListLazy =
     m (Endo [o], a) -> m ([o], a)
forall o (f :: * -> *) a.
(Monoid o, Functor f) =>
f (Endo o, a) -> f (o, a)
fromEndoWriter
  (m (Endo [o], a) -> m ([o], a))
-> (TellLazyC (Endo [o]) m a -> m (Endo [o], a))
-> TellLazyC (Endo [o]) m a
-> m ([o], a)
forall b c a. (b -> c) -> (a -> b) -> a -> c
.  TellLazyC (Endo [o]) m a -> m (Endo [o], a)
forall o (m :: * -> *) a (p :: [Effect]).
(Monoid o, Carrier m, Threaders '[WriterLazyThreads] m p) =>
TellLazyC o m a -> m (o, a)
runTellLazy
  (TellLazyC (Endo [o]) m a -> m ([o], a))
-> (ReinterpretC
      TellListLazyH
      (Tell o)
      '[Tell (Endo [o])]
      (TellLazyC (Endo [o]) m)
      a
    -> TellLazyC (Endo [o]) m a)
-> ReinterpretC
     TellListLazyH
     (Tell o)
     '[Tell (Endo [o])]
     (TellLazyC (Endo [o]) m)
     a
-> m ([o], a)
forall b a c. Coercible b a => (b -> c) -> (a -> b) -> a -> c
.# ReinterpretC
  TellListLazyH
  (Tell o)
  '[Tell (Endo [o])]
  (TellLazyC (Endo [o]) m)
  a
-> TellLazyC (Endo [o]) m a
forall h (e :: Effect) (new :: [Effect]) (m :: * -> *) a.
(Handler h e m, KnownList new, HeadEffs new m) =>
ReinterpretC h e new m a -> m a
reinterpretViaHandler
  (ReinterpretC
   TellListLazyH
   (Tell o)
   '[Tell (Endo [o])]
   (TellLazyC (Endo [o]) m)
   a
 -> m ([o], a))
-> (TellListLazyC o m a
    -> ReinterpretC
         TellListLazyH
         (Tell o)
         '[Tell (Endo [o])]
         (TellLazyC (Endo [o]) m)
         a)
-> TellListLazyC o m a
-> m ([o], a)
forall b a c. Coercible b a => (b -> c) -> (a -> b) -> a -> c
.# TellListLazyC o m a
-> ReinterpretC
     TellListLazyH
     (Tell o)
     '[Tell (Endo [o])]
     (TellLazyC (Endo [o]) m)
     a
forall (ts :: [Effect]) (m :: * -> *) a.
CompositionC ts m a -> CompositionBaseM ts m a
runComposition
{-# INLINE runTellListLazy #-}


-- | Run a @'Tell' o@ effect, where @o@ is a 'Monoid', by accumulating
-- all the uses of 'tell'.
--
-- You may want to combine this with 'tellIntoTell'.
--
-- Unlike 'runListen' and 'runWriter', this does not provide the ability to
-- interact with the 'tell's through 'listen' and 'pass'; but also doesn't
-- impose any primitive effects, meaning 'runTell' doesn't restrict what
-- interpreters are run before it.
--
-- @'Derivs' ('TellC' o m) = 'Tell' o ': 'Derivs' m@
--
-- @'Prims'  ('TellC' o m) = 'Prims' m@
--
-- This produces the final accumulation @o@ strictly. See 'runTellLazy' for a
-- lazy variant of this.
runTell :: forall o m a p
         . ( Monoid o
           , Carrier m
           , Threaders '[WriterThreads] m p
           )
        => TellC o m a
        -> m (o, a)
runTell :: TellC o m a -> m (o, a)
runTell (TellC WriterT o m a
m) = do
  (a
a, o
o) <- WriterT o m a -> m (a, o)
forall w (m :: * -> *) a. Monoid w => WriterT w m a -> m (a, w)
W.runWriterT WriterT o m a
m
  (o, a) -> m (o, a)
forall (m :: * -> *) a. Monad m => a -> m a
return (o
o, a
a)
{-# INLINE runTell #-}

-- | Run connected @'Listen' o@ and @'Tell' o@ effects, where @o@ is a 'Monoid',
-- by accumulating all the uses of 'tell'.
--
-- Unlike 'runWriter', this does not provide the power of 'pass'; but because
-- of that, it also doesn't impose 'Pass' as a primitive effect, meaning
-- a larger variety of interpreters may be run before 'runListen' compared to
-- 'runWriter'.
--
-- @'Derivs' ('ListenC' o m) = 'Listen' o ': 'Tell' o ': 'Derivs' m@
--
-- @'Prims'  ('ListenC' o m) = 'ListenPrim' o ': 'Prims' m@
--
-- This produces the final accumulation strictly. See 'runListenLazy' for a
-- lazy variant of this.
runListen :: forall o m a p
           . ( Monoid o
             , Carrier m
             , Threaders '[WriterThreads] m p
             )
          => ListenC o m a
          -> m (o, a)
runListen :: ListenC o m a -> m (o, a)
runListen (ListenC WriterT o m a
m) = do
  (a
a, o
o) <- WriterT o m a -> m (a, o)
forall w (m :: * -> *) a. Monoid w => WriterT w m a -> m (a, w)
W.runWriterT WriterT o m a
m
  (o, a) -> m (o, a)
forall (m :: * -> *) a. Monad m => a -> m a
return (o
o, a
a)
{-# INLINE runListen #-}

-- | Run connected @'Pass' o@, @'Listen' o@ and @'Tell' o@ effects,
-- -- i.e. @'Writer' o@ -- where @o@ is a 'Monoid', by accumulating all the
-- uses of 'tell'.
--
-- @'Pass' o@ is a fairly restrictive primitive effect. Notably,
-- 'Control.Effect.Cont.runCont' can't be used before 'runWriter'.
-- If you don't need 'pass', consider using 'runTell' or 'runListen' instead.
--
-- @'Derivs' ('WriterC' o m) = 'Pass' o ': 'Listen' o ': 'Tell' o ': 'Derivs' m@
--
-- @'Prims'  ('WriterC' o m) = 'WriterPrim' o ': 'Prims' m@
--
-- This produces the final accumulation strictly. See 'runWriterLazy' for a
-- lazy variant of this.
runWriter :: forall o m a p
           . ( Monoid o
             , Carrier m
             , Threaders '[WriterThreads] m p
             )
          => WriterC o m a
          -> m (o, a)
runWriter :: WriterC o m a -> m (o, a)
runWriter (WriterC WriterT o m a
m) = do
  (a
a, o
o) <- WriterT o m a -> m (a, o)
forall w (m :: * -> *) a. Monoid w => WriterT w m a -> m (a, w)
W.runWriterT WriterT o m a
m
  (o, a) -> m (o, a)
forall (m :: * -> *) a. Monad m => a -> m a
return (o
o, a
a)
{-# INLINE runWriter #-}


-- | Run a @'Tell' o@ effect, where @o@ is a 'Monoid', by accumulating all the
-- uses of 'tell' lazily.
--
-- @'Derivs' ('TellLazyC' o m) = 'Tell' o ': 'Derivs' m@
--
-- @'Prims'  ('TellLazyC' o m) = 'Prims' m@
--
-- This is a variant of 'runTell' that produces the final accumulation
-- lazily. __Use this only if you need__
-- __the laziness, as this would otherwise incur an unneccesary space leak.__
runTellLazy :: forall o m a p
         . ( Monoid o
           , Carrier m
           , Threaders '[WriterLazyThreads] m p
           )
        => TellLazyC o m a
        -> m (o, a)
runTellLazy :: TellLazyC o m a -> m (o, a)
runTellLazy (TellLazyC WriterT o m a
m) = (a, o) -> (o, a)
forall a b. (a, b) -> (b, a)
swap ((a, o) -> (o, a)) -> m (a, o) -> m (o, a)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> WriterT o m a -> m (a, o)
forall w (m :: * -> *) a. WriterT w m a -> m (a, w)
LW.runWriterT WriterT o m a
m
{-# INLINE runTellLazy #-}

-- | Run connected @'Listen' o@ and @'Tell' o@ effects,
-- where @o@ is a 'Monoid', by accumulating all the uses of 'tell' lazily.
--
-- @'Derivs' ('ListenLazyC' o m) = 'Listen' o ': 'Tell' o ': 'Derivs' m@
--
-- @'Prims'  ('ListenLazyC' o m) = 'ListenPrim' o ': 'Prims' m@
--
-- This is a variant of 'runListen' that produces the
-- final accumulation lazily. __Use this only if you need__
-- __the laziness, as this would otherwise incur an unneccesary space leak.__
runListenLazy :: forall o m a p
           . ( Monoid o
             , Carrier m
             , Threaders '[WriterThreads] m p
             )
          => ListenLazyC o m a
          -> m (o, a)
runListenLazy :: ListenLazyC o m a -> m (o, a)
runListenLazy (ListenLazyC WriterT o m a
m) = (a, o) -> (o, a)
forall a b. (a, b) -> (b, a)
swap ((a, o) -> (o, a)) -> m (a, o) -> m (o, a)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> WriterT o m a -> m (a, o)
forall w (m :: * -> *) a. WriterT w m a -> m (a, w)
LW.runWriterT WriterT o m a
m
{-# INLINE runListenLazy #-}

-- | Run connected @'Pass' o@, @'Listen' o@ and @'Tell' o@ effects,
-- -- i.e. @'Writer' o@ -- where @o@ is a 'Monoid',
-- by accumulating all the uses of 'tell' lazily.
--
-- @'Derivs' ('ListenLazyC' o m) = 'Pass' o ': 'Listen' o ': 'Tell' o ': 'Derivs' m@
--
-- @'Prims'  ('ListenLazyC' o m) = 'WriterPrim' o ': 'Prims' m@
--
-- This is a variant of 'runListen' that produces the
-- final accumulation lazily. __Use this only if you need__
-- __the laziness, as this would otherwise incur an unneccesary space leak.__
runWriterLazy :: forall o m a p
               . ( Monoid o
                 , Carrier m
                 , Threaders '[WriterLazyThreads] m p
                 )
              => WriterLazyC o m a
              -> m (o, a)
runWriterLazy :: WriterLazyC o m a -> m (o, a)
runWriterLazy (WriterLazyC WriterT o m a
m) = (a, o) -> (o, a)
forall a b. (a, b) -> (b, a)
swap ((a, o) -> (o, a)) -> m (a, o) -> m (o, a)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> WriterT o m a -> m (a, o)
forall w (m :: * -> *) a. WriterT w m a -> m (a, w)
LW.runWriterT WriterT o m a
m
{-# INLINE runWriterLazy #-}

tellTVar :: ( Monoid o
            , Effs '[Ask (o -> STM ()), Embed IO] m
            )
         => o
         -> m ()
tellTVar :: o -> m ()
tellTVar o
o = do
  o -> STM ()
write <- m (o -> STM ())
forall i (m :: * -> *). Eff (Ask i) m => m i
ask
  IO () -> m ()
forall (b :: * -> *) (m :: * -> *) a. Eff (Embed b) m => b a -> m a
embed (IO () -> m ()) -> IO () -> m ()
forall a b. (a -> b) -> a -> b
$ STM () -> IO ()
forall a. STM a -> IO a
atomically (STM () -> IO ()) -> STM () -> IO ()
forall a b. (a -> b) -> a -> b
$ o -> STM ()
write o
o
{-# INLINE tellTVar #-}


data WriterToEndoWriterH

instance (Monoid o, Eff (Tell (Endo o)) m)
      => Handler WriterToEndoWriterH (Tell o) m where
  effHandler :: Tell o (Effly z) x -> Effly z x
effHandler (Tell o
o) = Endo o -> Effly z ()
forall o (m :: * -> *). Eff (Tell o) m => o -> m ()
tell ((o -> o) -> Endo o
forall a. (a -> a) -> Endo a
Endo (o
o o -> o -> o
forall a. Semigroup a => a -> a -> a
<>))
  {-# INLINEABLE effHandler #-}

instance (Monoid o, Eff (Listen (Endo o)) m)
      => Handler WriterToEndoWriterH (Listen o) m where
  effHandler :: Listen o (Effly z) x -> Effly z x
effHandler (Listen Effly z a
m) =
    (((Endo o, a) -> (o, a)) -> Effly z (Endo o, a) -> Effly z (o, a)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (((Endo o, a) -> (o, a)) -> Effly z (Endo o, a) -> Effly z (o, a))
-> ((Endo o -> o) -> (Endo o, a) -> (o, a))
-> (Endo o -> o)
-> Effly z (Endo o, a)
-> Effly z (o, a)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Endo o -> o) -> (Endo o, a) -> (o, a)
forall (p :: * -> * -> *) a b c.
Bifunctor p =>
(a -> b) -> p a c -> p b c
first) (\(Endo o -> o
f) -> o -> o
f o
forall a. Monoid a => a
mempty) (Effly z (Endo o, a) -> Effly z (o, a))
-> Effly z (Endo o, a) -> Effly z (o, a)
forall a b. (a -> b) -> a -> b
$ Effly z a -> Effly z (Endo o, a)
forall o (m :: * -> *) a. Eff (Listen o) m => m a -> m (o, a)
listen Effly z a
m
  {-# INLINEABLE effHandler #-}

instance (Monoid o, Eff (Pass (Endo o)) m)
      => Handler WriterToEndoWriterH (Pass o) m where
  effHandler :: Pass o (Effly z) x -> Effly z x
effHandler (Pass Effly z (o -> o, x)
m) =
    Effly z (Endo o -> Endo o, x) -> Effly z x
forall o (m :: * -> *) a. Eff (Pass o) m => m (o -> o, a) -> m a
pass (Effly z (Endo o -> Endo o, x) -> Effly z x)
-> Effly z (Endo o -> Endo o, x) -> Effly z x
forall a b. (a -> b) -> a -> b
$
      (((o -> o, x) -> (Endo o -> Endo o, x))
-> Effly z (o -> o, x) -> Effly z (Endo o -> Endo o, x)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (((o -> o, x) -> (Endo o -> Endo o, x))
 -> Effly z (o -> o, x) -> Effly z (Endo o -> Endo o, x))
-> (((o -> o) -> Endo o -> Endo o)
    -> (o -> o, x) -> (Endo o -> Endo o, x))
-> ((o -> o) -> Endo o -> Endo o)
-> Effly z (o -> o, x)
-> Effly z (Endo o -> Endo o, x)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ((o -> o) -> Endo o -> Endo o)
-> (o -> o, x) -> (Endo o -> Endo o, x)
forall (p :: * -> * -> *) a b c.
Bifunctor p =>
(a -> b) -> p a c -> p b c
first)
        (\o -> o
f (Endo o -> o
ss) -> let !s' :: o
s' = o -> o
f (o -> o
ss o
forall a. Monoid a => a
mempty) in (o -> o) -> Endo o
forall a. (a -> a) -> Endo a
Endo (o
s' o -> o -> o
forall a. Semigroup a => a -> a -> a
<>))
        Effly z (o -> o, x)
m
  {-# INLINEABLE effHandler #-}

fromEndoWriter :: (Monoid o, Functor f)
               => f (Endo o, a)
               -> f (o, a)
fromEndoWriter :: f (Endo o, a) -> f (o, a)
fromEndoWriter = (((Endo o, a) -> (o, a)) -> f (Endo o, a) -> f (o, a)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (((Endo o, a) -> (o, a)) -> f (Endo o, a) -> f (o, a))
-> ((Endo o -> o) -> (Endo o, a) -> (o, a))
-> (Endo o -> o)
-> f (Endo o, a)
-> f (o, a)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Endo o -> o) -> (Endo o, a) -> (o, a)
forall (p :: * -> * -> *) a b c.
Bifunctor p =>
(a -> b) -> p a c -> p b c
first) (\(Endo o -> o
f) -> o -> o
f o
forall a. Monoid a => a
mempty)
{-# INLINE fromEndoWriter #-}

type TellIntoEndoTellC o =
  ReinterpretC WriterToEndoWriterH (Tell o) '[Tell (Endo o)]

-- | Rewrite a @'Tell' o@ effect into a @'Tell' ('Endo' o)@ effect.
--
-- This effectively right-associates all uses of 'tell', which
-- asymptotically improves performance if the time complexity of '<>' for the
-- 'Monoid' depends only on the size of the first argument.
-- In particular, you should use this (if you can be bothered) if the monoid
-- is a list, such as 'String'.
--
-- Usage is to combine this with the 'Tell' interpreter of your choice, followed
-- by 'fromEndoWriter', like this:
--
-- @
--    'run'
--  $ ...
--  $ 'fromEndoWriter'
--  $ 'runTell'
--  $ 'tellIntoEndoTell' \@String -- The 'Monoid' must be specified
--  $ ...
-- @
tellIntoEndoTell :: ( Monoid o
                    , HeadEff (Tell (Endo o)) m
                    )
                 => TellIntoEndoTellC o m a
                 -> m a
tellIntoEndoTell :: TellIntoEndoTellC o m a -> m a
tellIntoEndoTell = TellIntoEndoTellC o m a -> m a
forall h (e :: Effect) (new :: [Effect]) (m :: * -> *) a.
(Handler h e m, KnownList new, HeadEffs new m) =>
ReinterpretC h e new m a -> m a
reinterpretViaHandler
{-# INLINE tellIntoEndoTell #-}

type ListenIntoEndoListenC o = CompositionC
  '[ IntroC '[Listen o, Tell o] '[Listen (Endo o), Tell (Endo o)]
   , InterpretC WriterToEndoWriterH (Listen o)
   , InterpretC WriterToEndoWriterH (Tell o)
   ]

-- | Rewrite connected @'Listen' o@ and @'Tell' o@ effects into
-- connected @'Listen' ('Endo' o)@ and @'Tell' ('Endo' o)@ effects.
--
-- This effectively right-associates all uses of 'tell', which
-- asymptotically improves performance if the time complexity of '<>' for the
-- 'Monoid' depends only on the size of the first argument.
-- In particular, you should use this (if you can be bothered) if the monoid
-- is a list, such as String.
--
-- Usage is to combine this with the 'Listen' interpreter of your choice,
-- followed by 'fromEndoWriter', like this:
--
-- @
--    'run'
--  $ ...
--  $ 'fromEndoWriter'
--  $ 'runListen'
--  $ 'listenIntoEndoListen' \@String -- The 'Monoid' must be specified
--  $ ...
-- @
--
listenIntoEndoListen :: ( Monoid o
                        , HeadEffs '[Listen (Endo o), Tell (Endo o)] m
                        )
                     => ListenIntoEndoListenC o m a
                     -> m a
listenIntoEndoListen :: ListenIntoEndoListenC o m a -> m a
listenIntoEndoListen =
     InterpretC WriterToEndoWriterH (Tell o) m a -> m a
forall h (e :: Effect) (m :: * -> *) a.
Handler h e m =>
InterpretC h e m a -> m a
interpretViaHandler
  (InterpretC WriterToEndoWriterH (Tell o) m a -> m a)
-> (InterpretC
      WriterToEndoWriterH
      (Listen o)
      (InterpretC WriterToEndoWriterH (Tell o) m)
      a
    -> InterpretC WriterToEndoWriterH (Tell o) m a)
-> InterpretC
     WriterToEndoWriterH
     (Listen o)
     (InterpretC WriterToEndoWriterH (Tell o) m)
     a
-> m a
forall b a c. Coercible b a => (b -> c) -> (a -> b) -> a -> c
.# InterpretC
  WriterToEndoWriterH
  (Listen o)
  (InterpretC WriterToEndoWriterH (Tell o) m)
  a
-> InterpretC WriterToEndoWriterH (Tell o) m a
forall h (e :: Effect) (m :: * -> *) a.
Handler h e m =>
InterpretC h e m a -> m a
interpretViaHandler
  (InterpretC
   WriterToEndoWriterH
   (Listen o)
   (InterpretC WriterToEndoWriterH (Tell o) m)
   a
 -> m a)
-> (IntroUnderManyC
      '[Listen o, Tell o]
      '[Listen (Endo o), Tell (Endo o)]
      (InterpretC
         WriterToEndoWriterH
         (Listen o)
         (InterpretC WriterToEndoWriterH (Tell o) m))
      a
    -> InterpretC
         WriterToEndoWriterH
         (Listen o)
         (InterpretC WriterToEndoWriterH (Tell o) m)
         a)
-> IntroUnderManyC
     '[Listen o, Tell o]
     '[Listen (Endo o), Tell (Endo o)]
     (InterpretC
        WriterToEndoWriterH
        (Listen o)
        (InterpretC WriterToEndoWriterH (Tell o) m))
     a
-> m a
forall b a c. Coercible b a => (b -> c) -> (a -> b) -> a -> c
.# IntroUnderManyC
  '[Listen o, Tell o]
  '[Listen (Endo o), Tell (Endo o)]
  (InterpretC
     WriterToEndoWriterH
     (Listen o)
     (InterpretC WriterToEndoWriterH (Tell o) m))
  a
-> InterpretC
     WriterToEndoWriterH
     (Listen o)
     (InterpretC WriterToEndoWriterH (Tell o) m)
     a
forall (top :: [Effect]) (new :: [Effect]) (m :: * -> *) a.
(KnownList top, KnownList new, IntroConsistent top new m) =>
IntroUnderManyC top new m a -> m a
introUnderMany
  (IntroUnderManyC
   '[Listen o, Tell o]
   '[Listen (Endo o), Tell (Endo o)]
   (InterpretC
      WriterToEndoWriterH
      (Listen o)
      (InterpretC WriterToEndoWriterH (Tell o) m))
   a
 -> m a)
-> (ListenIntoEndoListenC o m a
    -> IntroUnderManyC
         '[Listen o, Tell o]
         '[Listen (Endo o), Tell (Endo o)]
         (InterpretC
            WriterToEndoWriterH
            (Listen o)
            (InterpretC WriterToEndoWriterH (Tell o) m))
         a)
-> ListenIntoEndoListenC o m a
-> m a
forall b a c. Coercible b a => (b -> c) -> (a -> b) -> a -> c
.# ListenIntoEndoListenC o m a
-> IntroUnderManyC
     '[Listen o, Tell o]
     '[Listen (Endo o), Tell (Endo o)]
     (InterpretC
        WriterToEndoWriterH
        (Listen o)
        (InterpretC WriterToEndoWriterH (Tell o) m))
     a
forall (ts :: [Effect]) (m :: * -> *) a.
CompositionC ts m a -> CompositionBaseM ts m a
runComposition
{-# INLINE listenIntoEndoListen #-}

type WriterIntoEndoWriterC o = CompositionC
  '[ IntroC '[Pass o, Listen o, Tell o]
            '[Pass (Endo o), Listen (Endo o), Tell (Endo o)]
   , InterpretC WriterToEndoWriterH (Pass o)
   , InterpretC WriterToEndoWriterH (Listen o)
   , InterpretC WriterToEndoWriterH (Tell o)
   ]

-- | Rewrite connected @'Pass' o@, @'Listen' o@ and @'Tell' o@ effects
-- -- i.e. @'Writer' o@ -- into connected @'Pass' ('Endo' o)@,
-- @'Listen' ('Endo' o)@ and @'Tell' ('Endo' o)@ effects on top of the effect
-- stack -- i.e. @'Writer' ('Endo' o)@.
--
-- This effectively right-associates all uses of 'tell', which
-- asymptotically improves performance if the time complexity of '<>' for the
-- 'Monoid' depends only on the size of the first argument.
-- In particular, you should use this (if you can be bothered) if the
-- monoid is a list, such as String.
--
-- Usage is to combine this with the 'Writer' interpreter of your choice,
-- followed by 'fromEndoWriter', like this:
--
-- @
--    'run'
--  $ ...
--  $ 'fromEndoWriter'
--  $ 'runWriter'
--  $ 'writerIntoEndoWriter' \@String -- The 'Monoid' must be specified
--  $ ...
-- @
writerIntoEndoWriter :: ( Monoid o
                        , HeadEffs
                           '[Pass (Endo o), Listen (Endo o), Tell (Endo o)]
                           m
                        )
                     => WriterIntoEndoWriterC o m a
                     -> m a
writerIntoEndoWriter :: WriterIntoEndoWriterC o m a -> m a
writerIntoEndoWriter =
     InterpretC WriterToEndoWriterH (Tell o) m a -> m a
forall h (e :: Effect) (m :: * -> *) a.
Handler h e m =>
InterpretC h e m a -> m a
interpretViaHandler
  (InterpretC WriterToEndoWriterH (Tell o) m a -> m a)
-> (InterpretC
      WriterToEndoWriterH
      (Listen o)
      (InterpretC WriterToEndoWriterH (Tell o) m)
      a
    -> InterpretC WriterToEndoWriterH (Tell o) m a)
-> InterpretC
     WriterToEndoWriterH
     (Listen o)
     (InterpretC WriterToEndoWriterH (Tell o) m)
     a
-> m a
forall b a c. Coercible b a => (b -> c) -> (a -> b) -> a -> c
.# InterpretC
  WriterToEndoWriterH
  (Listen o)
  (InterpretC WriterToEndoWriterH (Tell o) m)
  a
-> InterpretC WriterToEndoWriterH (Tell o) m a
forall h (e :: Effect) (m :: * -> *) a.
Handler h e m =>
InterpretC h e m a -> m a
interpretViaHandler
  (InterpretC
   WriterToEndoWriterH
   (Listen o)
   (InterpretC WriterToEndoWriterH (Tell o) m)
   a
 -> m a)
-> (InterpretC
      WriterToEndoWriterH
      (Pass o)
      (InterpretC
         WriterToEndoWriterH
         (Listen o)
         (InterpretC WriterToEndoWriterH (Tell o) m))
      a
    -> InterpretC
         WriterToEndoWriterH
         (Listen o)
         (InterpretC WriterToEndoWriterH (Tell o) m)
         a)
-> InterpretC
     WriterToEndoWriterH
     (Pass o)
     (InterpretC
        WriterToEndoWriterH
        (Listen o)
        (InterpretC WriterToEndoWriterH (Tell o) m))
     a
-> m a
forall b a c. Coercible b a => (b -> c) -> (a -> b) -> a -> c
.# InterpretC
  WriterToEndoWriterH
  (Pass o)
  (InterpretC
     WriterToEndoWriterH
     (Listen o)
     (InterpretC WriterToEndoWriterH (Tell o) m))
  a
-> InterpretC
     WriterToEndoWriterH
     (Listen o)
     (InterpretC WriterToEndoWriterH (Tell o) m)
     a
forall h (e :: Effect) (m :: * -> *) a.
Handler h e m =>
InterpretC h e m a -> m a
interpretViaHandler
  (InterpretC
   WriterToEndoWriterH
   (Pass o)
   (InterpretC
      WriterToEndoWriterH
      (Listen o)
      (InterpretC WriterToEndoWriterH (Tell o) m))
   a
 -> m a)
-> (IntroUnderManyC
      '[Pass o, Listen o, Tell o]
      '[Pass (Endo o), Listen (Endo o), Tell (Endo o)]
      (InterpretC
         WriterToEndoWriterH
         (Pass o)
         (InterpretC
            WriterToEndoWriterH
            (Listen o)
            (InterpretC WriterToEndoWriterH (Tell o) m)))
      a
    -> InterpretC
         WriterToEndoWriterH
         (Pass o)
         (InterpretC
            WriterToEndoWriterH
            (Listen o)
            (InterpretC WriterToEndoWriterH (Tell o) m))
         a)
-> IntroUnderManyC
     '[Pass o, Listen o, Tell o]
     '[Pass (Endo o), Listen (Endo o), Tell (Endo o)]
     (InterpretC
        WriterToEndoWriterH
        (Pass o)
        (InterpretC
           WriterToEndoWriterH
           (Listen o)
           (InterpretC WriterToEndoWriterH (Tell o) m)))
     a
-> m a
forall b a c. Coercible b a => (b -> c) -> (a -> b) -> a -> c
.# IntroUnderManyC
  '[Pass o, Listen o, Tell o]
  '[Pass (Endo o), Listen (Endo o), Tell (Endo o)]
  (InterpretC
     WriterToEndoWriterH
     (Pass o)
     (InterpretC
        WriterToEndoWriterH
        (Listen o)
        (InterpretC WriterToEndoWriterH (Tell o) m)))
  a
-> InterpretC
     WriterToEndoWriterH
     (Pass o)
     (InterpretC
        WriterToEndoWriterH
        (Listen o)
        (InterpretC WriterToEndoWriterH (Tell o) m))
     a
forall (top :: [Effect]) (new :: [Effect]) (m :: * -> *) a.
(KnownList top, KnownList new, IntroConsistent top new m) =>
IntroUnderManyC top new m a -> m a
introUnderMany
  (IntroUnderManyC
   '[Pass o, Listen o, Tell o]
   '[Pass (Endo o), Listen (Endo o), Tell (Endo o)]
   (InterpretC
      WriterToEndoWriterH
      (Pass o)
      (InterpretC
         WriterToEndoWriterH
         (Listen o)
         (InterpretC WriterToEndoWriterH (Tell o) m)))
   a
 -> m a)
-> (WriterIntoEndoWriterC o m a
    -> IntroUnderManyC
         '[Pass o, Listen o, Tell o]
         '[Pass (Endo o), Listen (Endo o), Tell (Endo o)]
         (InterpretC
            WriterToEndoWriterH
            (Pass o)
            (InterpretC
               WriterToEndoWriterH
               (Listen o)
               (InterpretC WriterToEndoWriterH (Tell o) m)))
         a)
-> WriterIntoEndoWriterC o m a
-> m a
forall b a c. Coercible b a => (b -> c) -> (a -> b) -> a -> c
.# WriterIntoEndoWriterC o m a
-> IntroUnderManyC
     '[Pass o, Listen o, Tell o]
     '[Pass (Endo o), Listen (Endo o), Tell (Endo o)]
     (InterpretC
        WriterToEndoWriterH
        (Pass o)
        (InterpretC
           WriterToEndoWriterH
           (Listen o)
           (InterpretC WriterToEndoWriterH (Tell o) m)))
     a
forall (ts :: [Effect]) (m :: * -> *) a.
CompositionC ts m a -> CompositionBaseM ts m a
runComposition
{-# INLINE writerIntoEndoWriter #-}

-- | Transform a 'Tell' effect into another 'Tell' effect by providing a function
-- to transform the type told.
--
-- This is useful to transform a @'Tell' o@ effect where @o@ isn't a 'Monoid'
-- into a @'Tell' o'@ effect where @o'@ /is/ a 'Monoid', and thus can be
-- interpreted using the various 'Monoid'al 'Tell' interpreters.
--
-- This has a higher-rank type, as it makes use of 'InterpretReifiedC'.
-- __This makes 'tellToTell' very difficult to use partially applied.__
-- __In particular, it can't be composed using @'.'@.__
--
-- If performance is secondary, consider using the slower
-- 'tellToTellSimple', which doesn't have a higher-rank type.
tellToTell :: forall o o' m a
            . Eff (Tell o') m
           => (o -> o')
           -> InterpretReifiedC (Tell o) m a
           -> m a
tellToTell :: (o -> o') -> InterpretReifiedC (Tell o) m a -> m a
tellToTell o -> o'
f = EffHandler (Tell o) m -> InterpretReifiedC (Tell o) m a -> m a
forall (e :: Effect) (m :: * -> *) a.
(RepresentationalEff e, Carrier m) =>
EffHandler e m -> InterpretReifiedC e m a -> m a
interpret (EffHandler (Tell o) m -> InterpretReifiedC (Tell o) m a -> m a)
-> EffHandler (Tell o) m -> InterpretReifiedC (Tell o) m a -> m a
forall a b. (a -> b) -> a -> b
$ \case
  Tell o -> o' -> Effly z ()
forall o (m :: * -> *). Eff (Tell o) m => o -> m ()
tell (o -> o'
f o
o)
{-# INLINE tellToTell #-}

-- | Transform a 'Tell' effect into another 'Tell' effect by providing a function
-- to transform the type told.
--
-- This is useful to transform a @'Tell' o@ where @o@ isn't a 'Monoid' into a
-- @'Tell' p@ effect where @p@ /is/ a 'Monoid', and thus can be interpreted using
-- the various 'Monoid'al 'Tell' interpreters.
--
-- This is a less performant version of 'tellToTell' that doesn't have
-- a higher-rank type, making it much easier to use partially applied.
tellToTellSimple :: forall o o' m a p
                  . ( Eff (Tell o') m
                    , Threaders '[ReaderThreads] m p
                    )
                 => (o -> o')
                 -> InterpretSimpleC (Tell o) m a
                 -> m a
tellToTellSimple :: (o -> o') -> InterpretSimpleC (Tell o) m a -> m a
tellToTellSimple o -> o'
f = EffHandler (Tell o) m -> InterpretSimpleC (Tell o) m a -> m a
forall (e :: Effect) (m :: * -> *) a (p :: [Effect]).
(RepresentationalEff e, Threaders '[ReaderThreads] m p,
 Carrier m) =>
EffHandler e m -> InterpretSimpleC e m a -> m a
interpretSimple (EffHandler (Tell o) m -> InterpretSimpleC (Tell o) m a -> m a)
-> EffHandler (Tell o) m -> InterpretSimpleC (Tell o) m a -> m a
forall a b. (a -> b) -> a -> b
$ \case
  Tell o -> o' -> Effly z ()
forall o (m :: * -> *). Eff (Tell o) m => o -> m ()
tell (o -> o'
f o
o)
{-# INLINE tellToTellSimple #-}

-- | Rewrite a 'Tell' effect into another 'Tell' effect on top of the effect
-- stack by providing a function to transform the type told.
--
-- This is useful to rewrite a @'Tell' o@ effect where @o@ isn't a 'Monoid'
-- into a @'Tell' t@ effect where @t@ /is/ a 'Monoid', and thus can be
-- interpreted using the various 'Monoid'al 'Tell' interpreters.
--
-- This has a higher-rank type, as it makes use of 'InterpretReifiedC'.
-- __This makes 'tellToTell' very difficult to use partially applied.__
-- __In particular, it can't be composed using @'.'@.__
--
-- If performance is secondary, consider using the slower
-- 'tellIntoTellSimple', which doesn't have a higher-rank type.
tellIntoTell :: forall o o' m a
              . HeadEff (Tell o') m
             => (o -> o')
             -> ReinterpretReifiedC (Tell o) '[Tell o'] m a
             -> m a
tellIntoTell :: (o -> o') -> ReinterpretReifiedC (Tell o) '[Tell o'] m a -> m a
tellIntoTell o -> o'
f = EffHandler (Tell o) m
-> ReinterpretReifiedC (Tell o) '[Tell o'] m a -> m a
forall (e :: Effect) (new :: [Effect]) (m :: * -> *) a.
(RepresentationalEff e, KnownList new, HeadEffs new m) =>
EffHandler e m -> ReinterpretReifiedC e new m a -> m a
reinterpret (EffHandler (Tell o) m
 -> ReinterpretReifiedC (Tell o) '[Tell o'] m a -> m a)
-> EffHandler (Tell o) m
-> ReinterpretReifiedC (Tell o) '[Tell o'] m a
-> m a
forall a b. (a -> b) -> a -> b
$ \case
  Tell o -> o' -> Effly z ()
forall o (m :: * -> *). Eff (Tell o) m => o -> m ()
tell (o -> o'
f o
o)
{-# INLINE tellIntoTell #-}

-- | Rewrite a 'Tell' effect into another 'Tell' effect on top of the effect
-- stack by providing a function to transform the type told.
--
-- This is useful to rewrite a @'Tell' o@ effect where @o@ isn't a 'Monoid'
-- into a @'Tell' o'@ effect where @o'@ /is/ a 'Monoid', and thus can be
-- interpreted using the various 'Monoid'al 'Tell' interpreters.
--
-- This is a less performant version of 'tellIntoTell' that doesn't have
-- a higher-rank type, making it much easier to use partially applied.
tellIntoTellSimple :: forall o o' m a p
                    . ( HeadEff (Tell o') m
                      , Threaders '[ReaderThreads] m p
                      )
                   => (o -> o')
                   -> ReinterpretSimpleC (Tell o) '[Tell o'] m a
                   -> m a
tellIntoTellSimple :: (o -> o') -> ReinterpretSimpleC (Tell o) '[Tell o'] m a -> m a
tellIntoTellSimple o -> o'
f = EffHandler (Tell o) m
-> ReinterpretSimpleC (Tell o) '[Tell o'] m a -> m a
forall (e :: Effect) (new :: [Effect]) (m :: * -> *) a
       (p :: [Effect]).
(RepresentationalEff e, KnownList new, HeadEffs new m,
 Threaders '[ReaderThreads] m p) =>
EffHandler e m -> ReinterpretSimpleC e new m a -> m a
reinterpretSimple (EffHandler (Tell o) m
 -> ReinterpretSimpleC (Tell o) '[Tell o'] m a -> m a)
-> EffHandler (Tell o) m
-> ReinterpretSimpleC (Tell o) '[Tell o'] m a
-> m a
forall a b. (a -> b) -> a -> b
$ \case
  Tell o -> o' -> Effly z ()
forall o (m :: * -> *). Eff (Tell o) m => o -> m ()
tell (o -> o'
f o
o)
{-# INLINE tellIntoTellSimple #-}



listenTVar :: forall o m a
            . ( Monoid o
              , Effs '[Reader (o -> STM ()), Embed IO, Bracket] m
              )
           => m a
           -> m (o, a)
listenTVar :: m a -> m (o, a)
listenTVar m a
main = do
  o -> STM ()
writeGlobal <- m (o -> STM ())
forall i (m :: * -> *). Eff (Ask i) m => m i
ask
  TVar o
localVar    <- IO (TVar o) -> m (TVar o)
forall (b :: * -> *) (m :: * -> *) a. Eff (Embed b) m => b a -> m a
embed (IO (TVar o) -> m (TVar o)) -> IO (TVar o) -> m (TVar o)
forall a b. (a -> b) -> a -> b
$ o -> IO (TVar o)
forall a. a -> IO (TVar a)
newTVarIO o
forall a. Monoid a => a
mempty
  TVar Bool
switch      <- IO (TVar Bool) -> m (TVar Bool)
forall (b :: * -> *) (m :: * -> *) a. Eff (Embed b) m => b a -> m a
embed (IO (TVar Bool) -> m (TVar Bool))
-> IO (TVar Bool) -> m (TVar Bool)
forall a b. (a -> b) -> a -> b
$ Bool -> IO (TVar Bool)
forall a. a -> IO (TVar a)
newTVarIO Bool
True
  let
    writeLocal :: o -> STM ()
    writeLocal :: o -> STM ()
writeLocal o
o = do
      Bool
writeToLocal <- TVar Bool -> STM Bool
forall a. TVar a -> STM a
readTVar TVar Bool
switch
      Bool -> STM () -> STM ()
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
when Bool
writeToLocal (STM () -> STM ()) -> STM () -> STM ()
forall a b. (a -> b) -> a -> b
$ do
        o
s <- TVar o -> STM o
forall a. TVar a -> STM a
readTVar TVar o
localVar
        TVar o -> o -> STM ()
forall a. TVar a -> a -> STM ()
writeTVar TVar o
localVar (o -> STM ()) -> o -> STM ()
forall a b. (a -> b) -> a -> b
$! o
s o -> o -> o
forall a. Semigroup a => a -> a -> a
<> o
o
      o -> STM ()
writeGlobal o
o
  a
a <- (((o -> STM ()) -> o -> STM ()) -> m a -> m a
forall i (m :: * -> *) a. Eff (Local i) m => (i -> i) -> m a -> m a
local (\o -> STM ()
_ -> o -> STM ()
writeLocal) m a
main)
         m a -> m () -> m a
forall (m :: * -> *) a b. Eff Bracket m => m a -> m b -> m a
`finally`
       (IO () -> m ()
forall (b :: * -> *) (m :: * -> *) a. Eff (Embed b) m => b a -> m a
embed (IO () -> m ()) -> IO () -> m ()
forall a b. (a -> b) -> a -> b
$ STM () -> IO ()
forall a. STM a -> IO a
atomically (STM () -> IO ()) -> STM () -> IO ()
forall a b. (a -> b) -> a -> b
$ TVar Bool -> Bool -> STM ()
forall a. TVar a -> a -> STM ()
writeTVar TVar Bool
switch Bool
False)
  o
o <- IO o -> m o
forall (b :: * -> *) (m :: * -> *) a. Eff (Embed b) m => b a -> m a
embed (IO o -> m o) -> IO o -> m o
forall a b. (a -> b) -> a -> b
$ TVar o -> IO o
forall a. TVar a -> IO a
readTVarIO TVar o
localVar
  (o, a) -> m (o, a)
forall (m :: * -> *) a. Monad m => a -> m a
return (o
o, a
a)

passTVar :: forall o m a
          . ( Monoid o
            , Effs '[Reader (o -> STM ()), Embed IO, Bracket] m
            )
         => m (o -> o, a)
         -> m a
passTVar :: m (o -> o, a) -> m a
passTVar m (o -> o, a)
main = do
  o -> STM ()
writeGlobal <- m (o -> STM ())
forall i (m :: * -> *). Eff (Ask i) m => m i
ask
  TVar o
localVar    <- IO (TVar o) -> m (TVar o)
forall (b :: * -> *) (m :: * -> *) a. Eff (Embed b) m => b a -> m a
embed (IO (TVar o) -> m (TVar o)) -> IO (TVar o) -> m (TVar o)
forall a b. (a -> b) -> a -> b
$ o -> IO (TVar o)
forall a. a -> IO (TVar a)
newTVarIO o
forall a. Monoid a => a
mempty
  TVar Bool
switch      <- IO (TVar Bool) -> m (TVar Bool)
forall (b :: * -> *) (m :: * -> *) a. Eff (Embed b) m => b a -> m a
embed (IO (TVar Bool) -> m (TVar Bool))
-> IO (TVar Bool) -> m (TVar Bool)
forall a b. (a -> b) -> a -> b
$ Bool -> IO (TVar Bool)
forall a. a -> IO (TVar a)
newTVarIO Bool
True
  let
    writeLocal :: o -> STM ()
    writeLocal :: o -> STM ()
writeLocal o
o = do
      Bool
writeToLocal <- TVar Bool -> STM Bool
forall a. TVar a -> STM a
readTVar TVar Bool
switch
      if Bool
writeToLocal then do
        o
s <- TVar o -> STM o
forall a. TVar a -> STM a
readTVar TVar o
localVar
        TVar o -> o -> STM ()
forall a. TVar a -> a -> STM ()
writeTVar TVar o
localVar (o -> STM ()) -> o -> STM ()
forall a b. (a -> b) -> a -> b
$! o
s o -> o -> o
forall a. Semigroup a => a -> a -> a
<> o
o
      else
        o -> STM ()
writeGlobal o
o

    commit :: (o -> o) -> IO ()
    commit :: (o -> o) -> IO ()
commit o -> o
f = STM () -> IO ()
forall a. STM a -> IO a
atomically (STM () -> IO ()) -> STM () -> IO ()
forall a b. (a -> b) -> a -> b
$ do
      Bool
notAlreadyCommited <- TVar Bool -> STM Bool
forall a. TVar a -> STM a
readTVar TVar Bool
switch
      Bool -> STM () -> STM ()
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
when Bool
notAlreadyCommited (STM () -> STM ()) -> STM () -> STM ()
forall a b. (a -> b) -> a -> b
$ do
        o
o <- TVar o -> STM o
forall a. TVar a -> STM a
readTVar TVar o
localVar
        o -> STM ()
writeGlobal (o -> o
f o
o)
        TVar Bool -> Bool -> STM ()
forall a. TVar a -> a -> STM ()
writeTVar TVar Bool
switch Bool
False

  ((o -> o
_, a
a), ()
_) <-
    m ()
-> (() -> ExitCase (o -> o, a) -> m ())
-> (() -> m (o -> o, a))
-> m ((o -> o, a), ())
forall (m :: * -> *) a b c.
Eff Bracket m =>
m a -> (a -> ExitCase b -> m c) -> (a -> m b) -> m (b, c)
generalBracket
      (() -> m ()
forall (f :: * -> *) a. Applicative f => a -> f a
pure ())
      (\()
_ -> \case
        ExitCaseSuccess (o -> o
f, a
_) -> IO () -> m ()
forall (b :: * -> *) (m :: * -> *) a. Eff (Embed b) m => b a -> m a
embed ((o -> o) -> IO ()
commit o -> o
f)
        ExitCase (o -> o, a)
_                      -> IO () -> m ()
forall (b :: * -> *) (m :: * -> *) a. Eff (Embed b) m => b a -> m a
embed ((o -> o) -> IO ()
commit o -> o
forall a. a -> a
id)
      )
      (\()
_ -> ((o -> STM ()) -> o -> STM ()) -> m (o -> o, a) -> m (o -> o, a)
forall i (m :: * -> *) a. Eff (Local i) m => (i -> i) -> m a -> m a
local (\o -> STM ()
_ -> o -> STM ()
writeLocal) m (o -> o, a)
main)
  a -> m a
forall (m :: * -> *) a. Monad m => a -> m a
return a
a

data WriterToBracketH

type WriterToBracketC o = CompositionC
 '[ IntroC '[Pass o, Listen o, Tell o] '[Local (o -> STM ()), Ask (o -> STM ())]
  , InterpretC WriterToBracketH (Pass o)
  , InterpretC WriterToBracketH (Listen o)
  , InterpretC WriterTVarH (Tell o)
  , ReaderC (o -> STM ())
  ]

instance ( Monoid o
         , Effs '[Reader (o -> STM ()), Embed IO, Bracket] m
         )
      => Handler WriterToBracketH (Listen o) m where
  effHandler :: Listen o (Effly z) x -> Effly z x
effHandler (Listen Effly z a
m) = Effly z a -> Effly z (o, a)
forall o (m :: * -> *) a.
(Monoid o, Effs '[Reader (o -> STM ()), Embed IO, Bracket] m) =>
m a -> m (o, a)
listenTVar Effly z a
m
  {-# INLINEABLE effHandler #-}

instance ( Monoid o
         , Effs '[Reader (o -> STM ()), Embed IO, Bracket] m
         )
      => Handler WriterToBracketH (Pass o) m where
  effHandler :: Pass o (Effly z) x -> Effly z x
effHandler (Pass Effly z (o -> o, x)
m) = Effly z (o -> o, x) -> Effly z x
forall o (m :: * -> *) a.
(Monoid o, Effs '[Reader (o -> STM ()), Embed IO, Bracket] m) =>
m (o -> o, a) -> m a
passTVar Effly z (o -> o, x)
m
  {-# INLINEABLE effHandler #-}

-- | Run connected @'Pass' o@, @'Listen' o@ and @'Tell' o@ effects
-- -- i.e. @'Writer' o@ -- by accumulating uses of 'tell' through using atomic
-- operations in 'IO', relying on the provided protection of 'Bracket' for
-- the implementation.
--
-- @'Derivs' ('WriterToBracketC' o m) = 'Pass' o ': 'Listen' o : 'Tell' o ': 'Derivs' m@
--
-- @'Prims'  ('WriterToBracketC' o m) = 'Control.Effect.Type.ReaderPrim.ReaderPrim' (o -> STM ()) ': 'Prims' m@
--
-- Note that unlike 'tellToIO', this does not have a higher-rank type.
writerToBracket :: forall o m a p
                 . ( Monoid o
                   , Effs [Embed IO, Bracket] m
                   , Threaders '[ReaderThreads] m p
                   )
                => WriterToBracketC o m a
                -> m (o, a)
writerToBracket :: WriterToBracketC o m a -> m (o, a)
writerToBracket WriterToBracketC o m a
m = do
  TVar o
tvar <- IO (TVar o) -> m (TVar o)
forall (b :: * -> *) (m :: * -> *) a. Eff (Embed b) m => b a -> m a
embed (IO (TVar o) -> m (TVar o)) -> IO (TVar o) -> m (TVar o)
forall a b. (a -> b) -> a -> b
$ o -> IO (TVar o)
forall a. a -> IO (TVar a)
newTVarIO o
forall a. Monoid a => a
mempty
  a
a    <- TVar o -> WriterToBracketC o m a -> m a
forall o (m :: * -> *) a (p :: [Effect]).
(Monoid o, Effs '[Embed IO, Bracket] m,
 Threaders '[ReaderThreads] m p) =>
TVar o -> WriterToBracketC o m a -> m a
writerToBracketTVar TVar o
tvar WriterToBracketC o m a
m
  o
o    <- IO o -> m o
forall (b :: * -> *) (m :: * -> *) a. Eff (Embed b) m => b a -> m a
embed (IO o -> m o) -> IO o -> m o
forall a b. (a -> b) -> a -> b
$ TVar o -> IO o
forall a. TVar a -> IO a
readTVarIO TVar o
tvar
  (o, a) -> m (o, a)
forall (m :: * -> *) a. Monad m => a -> m a
return (o
o, a
a)
{-# INLINE writerToBracket #-}

-- | Run connected @'Pass' o@, @'Listen' o@ and @'Tell' o@ effects
-- -- i.e. @'Writer' o@ -- by accumulating uses of 'tell' through using atomic
-- operations in 'IO' over a 'TVar', relying on the provided protection
-- of 'Bracket' for the implementation.
--
-- @'Derivs' ('WriterToBracketC' o m) = 'Pass' o ': 'Listen' o : 'Tell' o ': 'Derivs' m@
--
-- @'Prims'  ('WriterToBracketC' o m) = 'Control.Effect.Type.ReaderPrim.ReaderPrim' (o -> STM ()) ': 'Prims' m@
--
-- Note that unlike 'runTellTVar', this does not have a higher-rank type.
writerToBracketTVar :: forall o m a p
                     . ( Monoid o
                       , Effs [Embed IO, Bracket] m
                       , Threaders '[ReaderThreads] m p
                       )
                    => TVar o
                    -> WriterToBracketC o m a
                    -> m a
writerToBracketTVar :: TVar o -> WriterToBracketC o m a -> m a
writerToBracketTVar TVar o
tvar =
     (o -> STM ()) -> ReaderC (o -> STM ()) m a -> m a
forall i (m :: * -> *) a (p :: [Effect]).
(Carrier m, Threaders '[ReaderThreads] m p) =>
i -> ReaderC i m a -> m a
runReader (\o
o -> do
       o
s <- TVar o -> STM o
forall a. TVar a -> STM a
readTVar TVar o
tvar
       TVar o -> o -> STM ()
forall a. TVar a -> a -> STM ()
writeTVar TVar o
tvar (o -> STM ()) -> o -> STM ()
forall a b. (a -> b) -> a -> b
$! o
s o -> o -> o
forall a. Semigroup a => a -> a -> a
<> o
o
     )
  (ReaderC (o -> STM ()) m a -> m a)
-> (InterpretC WriterTVarH (Tell o) (ReaderC (o -> STM ()) m) a
    -> ReaderC (o -> STM ()) m a)
-> InterpretC WriterTVarH (Tell o) (ReaderC (o -> STM ()) m) a
-> m a
forall b a c. Coercible b a => (b -> c) -> (a -> b) -> a -> c
.# InterpretC WriterTVarH (Tell o) (ReaderC (o -> STM ()) m) a
-> ReaderC (o -> STM ()) m a
forall h (e :: Effect) (m :: * -> *) a.
Handler h e m =>
InterpretC h e m a -> m a
interpretViaHandler
  (InterpretC WriterTVarH (Tell o) (ReaderC (o -> STM ()) m) a
 -> m a)
-> (InterpretC
      WriterToBracketH
      (Listen o)
      (InterpretC WriterTVarH (Tell o) (ReaderC (o -> STM ()) m))
      a
    -> InterpretC WriterTVarH (Tell o) (ReaderC (o -> STM ()) m) a)
-> InterpretC
     WriterToBracketH
     (Listen o)
     (InterpretC WriterTVarH (Tell o) (ReaderC (o -> STM ()) m))
     a
-> m a
forall b a c. Coercible b a => (b -> c) -> (a -> b) -> a -> c
.# InterpretC
  WriterToBracketH
  (Listen o)
  (InterpretC WriterTVarH (Tell o) (ReaderC (o -> STM ()) m))
  a
-> InterpretC WriterTVarH (Tell o) (ReaderC (o -> STM ()) m) a
forall h (e :: Effect) (m :: * -> *) a.
Handler h e m =>
InterpretC h e m a -> m a
interpretViaHandler
  (InterpretC
   WriterToBracketH
   (Listen o)
   (InterpretC WriterTVarH (Tell o) (ReaderC (o -> STM ()) m))
   a
 -> m a)
-> (InterpretC
      WriterToBracketH
      (Pass o)
      (InterpretC
         WriterToBracketH
         (Listen o)
         (InterpretC WriterTVarH (Tell o) (ReaderC (o -> STM ()) m)))
      a
    -> InterpretC
         WriterToBracketH
         (Listen o)
         (InterpretC WriterTVarH (Tell o) (ReaderC (o -> STM ()) m))
         a)
-> InterpretC
     WriterToBracketH
     (Pass o)
     (InterpretC
        WriterToBracketH
        (Listen o)
        (InterpretC WriterTVarH (Tell o) (ReaderC (o -> STM ()) m)))
     a
-> m a
forall b a c. Coercible b a => (b -> c) -> (a -> b) -> a -> c
.# InterpretC
  WriterToBracketH
  (Pass o)
  (InterpretC
     WriterToBracketH
     (Listen o)
     (InterpretC WriterTVarH (Tell o) (ReaderC (o -> STM ()) m)))
  a
-> InterpretC
     WriterToBracketH
     (Listen o)
     (InterpretC WriterTVarH (Tell o) (ReaderC (o -> STM ()) m))
     a
forall h (e :: Effect) (m :: * -> *) a.
Handler h e m =>
InterpretC h e m a -> m a
interpretViaHandler
  (InterpretC
   WriterToBracketH
   (Pass o)
   (InterpretC
      WriterToBracketH
      (Listen o)
      (InterpretC WriterTVarH (Tell o) (ReaderC (o -> STM ()) m)))
   a
 -> m a)
-> (IntroUnderManyC
      '[Pass o, Listen o, Tell o]
      '[Local (o -> STM ()), Ask (o -> STM ())]
      (InterpretC
         WriterToBracketH
         (Pass o)
         (InterpretC
            WriterToBracketH
            (Listen o)
            (InterpretC WriterTVarH (Tell o) (ReaderC (o -> STM ()) m))))
      a
    -> InterpretC
         WriterToBracketH
         (Pass o)
         (InterpretC
            WriterToBracketH
            (Listen o)
            (InterpretC WriterTVarH (Tell o) (ReaderC (o -> STM ()) m)))
         a)
-> IntroUnderManyC
     '[Pass o, Listen o, Tell o]
     '[Local (o -> STM ()), Ask (o -> STM ())]
     (InterpretC
        WriterToBracketH
        (Pass o)
        (InterpretC
           WriterToBracketH
           (Listen o)
           (InterpretC WriterTVarH (Tell o) (ReaderC (o -> STM ()) m))))
     a
-> m a
forall b a c. Coercible b a => (b -> c) -> (a -> b) -> a -> c
.# IntroUnderManyC
  '[Pass o, Listen o, Tell o]
  '[Local (o -> STM ()), Ask (o -> STM ())]
  (InterpretC
     WriterToBracketH
     (Pass o)
     (InterpretC
        WriterToBracketH
        (Listen o)
        (InterpretC WriterTVarH (Tell o) (ReaderC (o -> STM ()) m))))
  a
-> InterpretC
     WriterToBracketH
     (Pass o)
     (InterpretC
        WriterToBracketH
        (Listen o)
        (InterpretC WriterTVarH (Tell o) (ReaderC (o -> STM ()) m)))
     a
forall (top :: [Effect]) (new :: [Effect]) (m :: * -> *) a.
(KnownList top, KnownList new, IntroConsistent top new m) =>
IntroUnderManyC top new m a -> m a
introUnderMany
  (IntroUnderManyC
   '[Pass o, Listen o, Tell o]
   '[Local (o -> STM ()), Ask (o -> STM ())]
   (InterpretC
      WriterToBracketH
      (Pass o)
      (InterpretC
         WriterToBracketH
         (Listen o)
         (InterpretC WriterTVarH (Tell o) (ReaderC (o -> STM ()) m))))
   a
 -> m a)
-> (WriterToBracketC o m a
    -> IntroUnderManyC
         '[Pass o, Listen o, Tell o]
         '[Local (o -> STM ()), Ask (o -> STM ())]
         (InterpretC
            WriterToBracketH
            (Pass o)
            (InterpretC
               WriterToBracketH
               (Listen o)
               (InterpretC WriterTVarH (Tell o) (ReaderC (o -> STM ()) m))))
         a)
-> WriterToBracketC o m a
-> m a
forall b a c. Coercible b a => (b -> c) -> (a -> b) -> a -> c
.# WriterToBracketC o m a
-> IntroUnderManyC
     '[Pass o, Listen o, Tell o]
     '[Local (o -> STM ()), Ask (o -> STM ())]
     (InterpretC
        WriterToBracketH
        (Pass o)
        (InterpretC
           WriterToBracketH
           (Listen o)
           (InterpretC WriterTVarH (Tell o) (ReaderC (o -> STM ()) m))))
     a
forall (ts :: [Effect]) (m :: * -> *) a.
CompositionC ts m a -> CompositionBaseM ts m a
runComposition
{-# INLINE writerToBracketTVar #-}

data WriterTVarH

type ListenTVarC o = CompositionC
 '[ IntroC '[Listen o, Tell o]
     '[ ListenPrim o
      , Local (o -> STM ())
      , Ask (o -> STM ())
      ]
  , InterpretC WriterTVarH (Listen o)
  , InterpretC WriterTVarH (Tell o)
  , InterpretPrimC WriterTVarH (ListenPrim o)
  , ReaderC (o -> STM ())
  ]

type WriterTVarC o = CompositionC
 '[ IntroC '[Pass o, Listen o, Tell o]
     '[ ListenPrim o
      , WriterPrim o
      , Local (o -> STM ())
      , Ask (o -> STM ())
      ]
  , InterpretC WriterTVarH (Pass o)
  , InterpretC WriterTVarH (Listen o)
  , InterpretC WriterTVarH (Tell o)
  , InterpretC WriterTVarH (ListenPrim o)
  , InterpretPrimC WriterTVarH (WriterPrim o)
  , ReaderC (o -> STM ())
  ]

instance ( Monoid o
         , Effs '[Reader (o -> STM ()), Embed IO] m
         )
      => Handler WriterTVarH (Tell o) m where
  effHandler :: Tell o (Effly z) x -> Effly z x
effHandler (Tell o
o) = o -> Effly z ()
forall o (m :: * -> *).
(Monoid o, Effs '[Ask (o -> STM ()), Embed IO] m) =>
o -> m ()
tellTVar o
o
  {-# INLINEABLE effHandler #-}

instance Eff (ListenPrim o) m
      => Handler WriterTVarH (Listen o) m where
  effHandler :: Listen o (Effly z) x -> Effly z x
effHandler (Listen Effly z a
m) = ListenPrim o (Effly z) (o, a) -> Effly z (o, a)
forall (e :: Effect) (m :: * -> *) a.
(Member e (Derivs m), Carrier m) =>
e m a -> m a
send (ListenPrim o (Effly z) (o, a) -> Effly z (o, a))
-> ListenPrim o (Effly z) (o, a) -> Effly z (o, a)
forall a b. (a -> b) -> a -> b
$ Effly z a -> ListenPrim o (Effly z) (o, a)
forall (m :: * -> *) a o. m a -> ListenPrim o m (o, a)
ListenPrimListen Effly z a
m
  {-# INLINEABLE effHandler #-}

instance Eff (WriterPrim o) m
      => Handler WriterTVarH (Pass o) m where
  effHandler :: Pass o (Effly z) x -> Effly z x
effHandler (Pass Effly z (o -> o, x)
m) = WriterPrim o (Effly z) x -> Effly z x
forall (e :: Effect) (m :: * -> *) a.
(Member e (Derivs m), Carrier m) =>
e m a -> m a
send (WriterPrim o (Effly z) x -> Effly z x)
-> WriterPrim o (Effly z) x -> Effly z x
forall a b. (a -> b) -> a -> b
$ Effly z (o -> o, x) -> WriterPrim o (Effly z) x
forall (m :: * -> *) o a. m (o -> o, a) -> WriterPrim o m a
WriterPrimPass Effly z (o -> o, x)
m
  {-# INLINEABLE effHandler #-}

instance Eff (WriterPrim o) m
      => Handler WriterTVarH (ListenPrim o) m where
  effHandler :: ListenPrim o (Effly z) x -> Effly z x
effHandler = \case
    ListenPrimTell o
o   -> WriterPrim o (Effly z) () -> Effly z ()
forall (e :: Effect) (m :: * -> *) a.
(Member e (Derivs m), Carrier m) =>
e m a -> m a
send (WriterPrim o (Effly z) () -> Effly z ())
-> WriterPrim o (Effly z) () -> Effly z ()
forall a b. (a -> b) -> a -> b
$ o -> WriterPrim o (Effly z) ()
forall o (m :: * -> *). o -> WriterPrim o m ()
WriterPrimTell o
o
    ListenPrimListen Effly z a
m -> WriterPrim o (Effly z) (o, a) -> Effly z (o, a)
forall (e :: Effect) (m :: * -> *) a.
(Member e (Derivs m), Carrier m) =>
e m a -> m a
send (WriterPrim o (Effly z) (o, a) -> Effly z (o, a))
-> WriterPrim o (Effly z) (o, a) -> Effly z (o, a)
forall a b. (a -> b) -> a -> b
$ Effly z a -> WriterPrim o (Effly z) (o, a)
forall (m :: * -> *) a o. m a -> WriterPrim o m (o, a)
WriterPrimListen Effly z a
m
  {-# INLINEABLE effHandler #-}

instance ( Monoid o
         , Effs '[Reader (o -> STM ()), Embed IO] m
         , C.MonadMask m
         )
      => PrimHandler WriterTVarH (ListenPrim o) m where
  effPrimHandler :: ListenPrim o m x -> m x
effPrimHandler = \case
    ListenPrimTell   o
o -> o -> m ()
forall o (m :: * -> *).
(Monoid o, Effs '[Ask (o -> STM ()), Embed IO] m) =>
o -> m ()
tellTVar o
o
    ListenPrimListen m a
m -> BracketToIOC m (o, a) -> m (o, a)
forall (m :: * -> *) a.
(Carrier m, MonadMask m) =>
BracketToIOC m a -> m a
bracketToIO (InterpretPrimC BracketToIOH Bracket m a -> BracketToIOC m (o, a)
forall o (m :: * -> *) a.
(Monoid o, Effs '[Reader (o -> STM ()), Embed IO, Bracket] m) =>
m a -> m (o, a)
listenTVar (m a -> InterpretPrimC BracketToIOH Bracket m a
forall (t :: Effect) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift m a
m))
  {-# INLINEABLE effPrimHandler #-}

instance ( Monoid o
         , Effs '[Reader (o -> STM ()), Embed IO] m
         , C.MonadMask m
         )
      => PrimHandler WriterTVarH (WriterPrim o) m where
  effPrimHandler :: WriterPrim o m x -> m x
effPrimHandler = \case
    WriterPrimTell   o
o -> o -> m ()
forall o (m :: * -> *).
(Monoid o, Effs '[Ask (o -> STM ()), Embed IO] m) =>
o -> m ()
tellTVar o
o
    WriterPrimListen m a
m -> BracketToIOC m (o, a) -> m (o, a)
forall (m :: * -> *) a.
(Carrier m, MonadMask m) =>
BracketToIOC m a -> m a
bracketToIO (InterpretPrimC BracketToIOH Bracket m a -> BracketToIOC m (o, a)
forall o (m :: * -> *) a.
(Monoid o, Effs '[Reader (o -> STM ()), Embed IO, Bracket] m) =>
m a -> m (o, a)
listenTVar (m a -> InterpretPrimC BracketToIOH Bracket m a
forall (t :: Effect) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift m a
m))
    WriterPrimPass   m (o -> o, x)
m -> BracketToIOC m x -> m x
forall (m :: * -> *) a.
(Carrier m, MonadMask m) =>
BracketToIOC m a -> m a
bracketToIO (InterpretPrimC BracketToIOH Bracket m (o -> o, x)
-> BracketToIOC m x
forall o (m :: * -> *) a.
(Monoid o, Effs '[Reader (o -> STM ()), Embed IO, Bracket] m) =>
m (o -> o, a) -> m a
passTVar (m (o -> o, x) -> InterpretPrimC BracketToIOH Bracket m (o -> o, x)
forall (t :: Effect) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift m (o -> o, x)
m))
  {-# INLINEABLE effPrimHandler #-}

-- | Run a @'Tell' o@ effect where @o@ is a 'Monoid' by accumulating uses of
-- 'tell' through atomic operations in 'IO'.
--
-- You may want to combine this with 'tellIntoTell'.
--
-- This has a higher-rank type, as it makes use of 'InterpretReifiedC'.
-- __This makes 'tellToIO' very difficult to use partially applied.__
-- __In particular, it can't be composed using @'.'@.__
--
-- If performance is secondary, consider using the slower
-- 'tellToIOSimple', which doesn't have a higher-rank type.
tellToIO :: forall o m a
          . ( Monoid o
            , Eff (Embed IO) m
            )
         => InterpretReifiedC (Tell o) m a
         -> m (o, a)
tellToIO :: InterpretReifiedC (Tell o) m a -> m (o, a)
tellToIO InterpretReifiedC (Tell o) m a
m = do
  IORef o
ref <- IO (IORef o) -> m (IORef o)
forall (b :: * -> *) (m :: * -> *) a. Eff (Embed b) m => b a -> m a
embed (IO (IORef o) -> m (IORef o)) -> IO (IORef o) -> m (IORef o)
forall a b. (a -> b) -> a -> b
$ o -> IO (IORef o)
forall a. a -> IO (IORef a)
newIORef o
forall a. Monoid a => a
mempty
  a
a   <- IORef o -> InterpretReifiedC (Tell o) m a -> m a
forall o (m :: * -> *) a.
(Monoid o, Eff (Embed IO) m) =>
IORef o -> InterpretReifiedC (Tell o) m a -> m a
runTellIORef IORef o
ref InterpretReifiedC (Tell o) m a
m
  o
o   <- IO o -> m o
forall (b :: * -> *) (m :: * -> *) a. Eff (Embed b) m => b a -> m a
embed (IO o -> m o) -> IO o -> m o
forall a b. (a -> b) -> a -> b
$ IORef o -> IO o
forall a. IORef a -> IO a
readIORef IORef o
ref
  (o, a) -> m (o, a)
forall (m :: * -> *) a. Monad m => a -> m a
return (o
o, a
a)
{-# INLINE tellToIO #-}

-- | Run a @'Tell' o@ effect where @o@ is a 'Monoid' by accumulating uses of
-- 'tell' through using atomic operations in 'IO' over the provided 'IORef'.
--
-- This has a higher-rank type, as it makes use of 'InterpretReifiedC'.
-- __This makes 'runTellIORef' very difficult to use partially applied.__
-- __In particular, it can't be composed using @'.'@.__
--
-- If performance is secondary, consider using the slower
-- 'runTellIORefSimple', which doesn't have a higher-rank type.
runTellIORef :: forall o m a
              . ( Monoid o
                , Eff (Embed IO) m
                )
             => IORef o
             -> InterpretReifiedC (Tell o) m a
             -> m a
runTellIORef :: IORef o -> InterpretReifiedC (Tell o) m a -> m a
runTellIORef IORef o
ref = EffHandler (Tell o) m -> InterpretReifiedC (Tell o) m a -> m a
forall (e :: Effect) (m :: * -> *) a.
(RepresentationalEff e, Carrier m) =>
EffHandler e m -> InterpretReifiedC e m a -> m a
interpret (EffHandler (Tell o) m -> InterpretReifiedC (Tell o) m a -> m a)
-> EffHandler (Tell o) m -> InterpretReifiedC (Tell o) m a -> m a
forall a b. (a -> b) -> a -> b
$ \case
  Tell o -> IO () -> Effly z ()
forall (b :: * -> *) (m :: * -> *) a. Eff (Embed b) m => b a -> m a
embed (IO () -> Effly z ()) -> IO () -> Effly z ()
forall a b. (a -> b) -> a -> b
$ IORef o -> (o -> (o, ())) -> IO ()
forall a b. IORef a -> (a -> (a, b)) -> IO b
atomicModifyIORef' IORef o
ref (\o
s -> (o
s o -> o -> o
forall a. Semigroup a => a -> a -> a
<> o
o, ()))
{-# INLINE runTellIORef #-}

-- | Run a @'Tell' o@ effect where @o@ is a 'Monoid' by accumulating uses of
-- 'tell' through using atomic operations in 'IO' over the provided 'TVar'.
--
-- This has a higher-rank type, as it makes use of 'InterpretReifiedC'.
-- __This makes 'runTellTVar' very difficult to use partially applied.__
-- __In particular, it can't be composed using @'.'@.__
--
-- If performance is secondary, consider using the slower
-- 'runTellTVarSimple', which doesn't have a higher-rank type.
runTellTVar :: forall o m a
             . ( Monoid o
               , Eff (Embed IO) m
               )
            => TVar o
            -> InterpretReifiedC (Tell o) m a
            -> m a
runTellTVar :: TVar o -> InterpretReifiedC (Tell o) m a -> m a
runTellTVar TVar o
tvar = EffHandler (Tell o) m -> InterpretReifiedC (Tell o) m a -> m a
forall (e :: Effect) (m :: * -> *) a.
(RepresentationalEff e, Carrier m) =>
EffHandler e m -> InterpretReifiedC e m a -> m a
interpret (EffHandler (Tell o) m -> InterpretReifiedC (Tell o) m a -> m a)
-> EffHandler (Tell o) m -> InterpretReifiedC (Tell o) m a -> m a
forall a b. (a -> b) -> a -> b
$ \case
  Tell o -> IO () -> Effly z ()
forall (b :: * -> *) (m :: * -> *) a. Eff (Embed b) m => b a -> m a
embed (IO () -> Effly z ()) -> IO () -> Effly z ()
forall a b. (a -> b) -> a -> b
$ STM () -> IO ()
forall a. STM a -> IO a
atomically (STM () -> IO ()) -> STM () -> IO ()
forall a b. (a -> b) -> a -> b
$ do
    o
s <- TVar o -> STM o
forall a. TVar a -> STM a
readTVar TVar o
tvar
    TVar o -> o -> STM ()
forall a. TVar a -> a -> STM ()
writeTVar TVar o
tvar (o -> STM ()) -> o -> STM ()
forall a b. (a -> b) -> a -> b
$! o
s o -> o -> o
forall a. Semigroup a => a -> a -> a
<> o
o
{-# INLINE runTellTVar #-}

-- | Run a @'Tell' o@ effect where @o@ is a 'Monoid' by accumulating uses of
-- 'tell' through atomic operations in 'IO'.
--
-- You may want to combine this with 'tellIntoTellSimple'.
--
-- This is a less performant version of 'tellToIO' that doesn't have
-- a higher-rank type, making it much easier to use partially applied.
tellToIOSimple :: forall o m a p
                . ( Monoid o
                  , Eff (Embed IO) m
                  , Threaders '[ReaderThreads] m p
                  )
               => InterpretSimpleC (Tell o) m a
               -> m (o, a)
tellToIOSimple :: InterpretSimpleC (Tell o) m a -> m (o, a)
tellToIOSimple InterpretSimpleC (Tell o) m a
m = do
  IORef o
ref <- IO (IORef o) -> m (IORef o)
forall (b :: * -> *) (m :: * -> *) a. Eff (Embed b) m => b a -> m a
embed (IO (IORef o) -> m (IORef o)) -> IO (IORef o) -> m (IORef o)
forall a b. (a -> b) -> a -> b
$ o -> IO (IORef o)
forall a. a -> IO (IORef a)
newIORef o
forall a. Monoid a => a
mempty
  a
a   <- IORef o -> InterpretSimpleC (Tell o) m a -> m a
forall o (m :: * -> *) a (p :: [Effect]).
(Monoid o, Eff (Embed IO) m, Threaders '[ReaderThreads] m p) =>
IORef o -> InterpretSimpleC (Tell o) m a -> m a
runTellIORefSimple IORef o
ref InterpretSimpleC (Tell o) m a
m
  o
o   <- IO o -> m o
forall (b :: * -> *) (m :: * -> *) a. Eff (Embed b) m => b a -> m a
embed (IO o -> m o) -> IO o -> m o
forall a b. (a -> b) -> a -> b
$ IORef o -> IO o
forall a. IORef a -> IO a
readIORef IORef o
ref
  (o, a) -> m (o, a)
forall (m :: * -> *) a. Monad m => a -> m a
return (o
o, a
a)
{-# INLINE tellToIOSimple #-}

-- | Run a @'Tell' o@ effect where @o@ is a 'Monoid' by accumulating uses of
-- 'tell' through using atomic operations in 'IO' over the provided 'IORef'.
--
-- This is a less performant version of 'tellToIO' that doesn't have
-- a higher-rank type, making it much easier to use partially applied.
runTellIORefSimple :: forall o m a p
                    . ( Monoid o
                      , Eff (Embed IO) m
                      , Threaders '[ReaderThreads] m p
                      )
                   => IORef o
                   -> InterpretSimpleC (Tell o) m a
                   -> m a
runTellIORefSimple :: IORef o -> InterpretSimpleC (Tell o) m a -> m a
runTellIORefSimple IORef o
ref = EffHandler (Tell o) m -> InterpretSimpleC (Tell o) m a -> m a
forall (e :: Effect) (m :: * -> *) a (p :: [Effect]).
(RepresentationalEff e, Threaders '[ReaderThreads] m p,
 Carrier m) =>
EffHandler e m -> InterpretSimpleC e m a -> m a
interpretSimple (EffHandler (Tell o) m -> InterpretSimpleC (Tell o) m a -> m a)
-> EffHandler (Tell o) m -> InterpretSimpleC (Tell o) m a -> m a
forall a b. (a -> b) -> a -> b
$ \case
  Tell o -> IO () -> Effly z ()
forall (b :: * -> *) (m :: * -> *) a. Eff (Embed b) m => b a -> m a
embed (IO () -> Effly z ()) -> IO () -> Effly z ()
forall a b. (a -> b) -> a -> b
$ IORef o -> (o -> (o, ())) -> IO ()
forall a b. IORef a -> (a -> (a, b)) -> IO b
atomicModifyIORef' IORef o
ref (\o
s -> (o
s o -> o -> o
forall a. Semigroup a => a -> a -> a
<> o
o, ()))
{-# INLINE runTellIORefSimple #-}

-- | Run a @'Tell' o@ effect where @o@ is a 'Monoid' by accumulating uses of
-- 'tell' through using atomic operations in 'IO' over the provided 'TVar'.
--
-- This is a less performant version of 'tellToIO' that doesn't have
-- a higher-rank type, making it much easier to use partially applied.
runTellTVarSimple :: forall o m a p
                   . ( Monoid o
                     , Eff (Embed IO) m
                     , Threaders '[ReaderThreads] m p
                     )
                  => TVar o
                  -> InterpretSimpleC (Tell o) m a
                  -> m a
runTellTVarSimple :: TVar o -> InterpretSimpleC (Tell o) m a -> m a
runTellTVarSimple TVar o
tvar = EffHandler (Tell o) m -> InterpretSimpleC (Tell o) m a -> m a
forall (e :: Effect) (m :: * -> *) a (p :: [Effect]).
(RepresentationalEff e, Threaders '[ReaderThreads] m p,
 Carrier m) =>
EffHandler e m -> InterpretSimpleC e m a -> m a
interpretSimple (EffHandler (Tell o) m -> InterpretSimpleC (Tell o) m a -> m a)
-> EffHandler (Tell o) m -> InterpretSimpleC (Tell o) m a -> m a
forall a b. (a -> b) -> a -> b
$ \case
  Tell o -> IO () -> Effly z ()
forall (b :: * -> *) (m :: * -> *) a. Eff (Embed b) m => b a -> m a
embed (IO () -> Effly z ()) -> IO () -> Effly z ()
forall a b. (a -> b) -> a -> b
$ STM () -> IO ()
forall a. STM a -> IO a
atomically (STM () -> IO ()) -> STM () -> IO ()
forall a b. (a -> b) -> a -> b
$ do
    o
s <- TVar o -> STM o
forall a. TVar a -> STM a
readTVar TVar o
tvar
    TVar o -> o -> STM ()
forall a. TVar a -> a -> STM ()
writeTVar TVar o
tvar (o -> STM ()) -> o -> STM ()
forall a b. (a -> b) -> a -> b
$! o
s o -> o -> o
forall a. Semigroup a => a -> a -> a
<> o
o
{-# INLINE runTellTVarSimple #-}

-- | Run connected @'Listen' o@ and @'Tell' o@ effects by accumulating uses of
-- 'tell' through using atomic operations in 'IO'.
--
-- @'Derivs' ('ListenTVarC' o m) = 'Listen' o ': 'Tell' o ': 'Derivs' m@
--
-- @'Prims'  ('ListenTVarC' o m) = 'ListenPrim' o ': 'Control.Effect.Type.ReaderPrim.ReaderPrim' (o -> STM ()) ': 'Prims' m@
--
-- Note that unlike 'tellToIO', this does not have a higher-rank type.
listenToIO :: forall o m a p
            . ( Monoid o
              , Eff (Embed IO) m
              , C.MonadMask m
              , Threaders '[ReaderThreads] m p
              )
           => ListenTVarC o m a
           -> m (o, a)
listenToIO :: ListenTVarC o m a -> m (o, a)
listenToIO ListenTVarC o m a
m = do
  TVar o
tvar <- IO (TVar o) -> m (TVar o)
forall (b :: * -> *) (m :: * -> *) a. Eff (Embed b) m => b a -> m a
embed (IO (TVar o) -> m (TVar o)) -> IO (TVar o) -> m (TVar o)
forall a b. (a -> b) -> a -> b
$ o -> IO (TVar o)
forall a. a -> IO (TVar a)
newTVarIO o
forall a. Monoid a => a
mempty
  a
a    <- TVar o -> ListenTVarC o m a -> m a
forall o (m :: * -> *) a (p :: [Effect]).
(Monoid o, Eff (Embed IO) m, MonadMask m,
 Threaders '[ReaderThreads] m p) =>
TVar o -> ListenTVarC o m a -> m a
runListenTVar TVar o
tvar ListenTVarC o m a
m
  o
o    <- IO o -> m o
forall (b :: * -> *) (m :: * -> *) a. Eff (Embed b) m => b a -> m a
embed (IO o -> m o) -> IO o -> m o
forall a b. (a -> b) -> a -> b
$ TVar o -> IO o
forall a. TVar a -> IO a
readTVarIO TVar o
tvar
  (o, a) -> m (o, a)
forall (m :: * -> *) a. Monad m => a -> m a
return (o
o, a
a)
{-# INLINE listenToIO #-}

-- | Run connected @'Listen' o@ and @'Tell' o@ effects by accumulating uses of
-- 'tell' through using atomic operations in 'IO' over the provided 'TVar'.
--
-- @'Derivs' ('ListenTVarC' o m) = 'Listen' o : 'Tell' o ': 'Derivs' m@
--
-- @'Prims'  ('ListenTVarC' o m) = 'ListenPrim' o ': 'Control.Effect.Type.ReaderPrim.ReaderPrim' (o -> STM ()) ': 'Prims' m@
--
-- Note that unlike 'runTellTVar', this does not have a higher-rank type.
runListenTVar :: forall o m a p
               . ( Monoid o
                 , Eff (Embed IO) m
                 , C.MonadMask m
                 , Threaders '[ReaderThreads] m p
                 )
              => TVar o
              -> ListenTVarC o m a
              -> m a
runListenTVar :: TVar o -> ListenTVarC o m a -> m a
runListenTVar TVar o
tvar =
     (o -> STM ()) -> ReaderC (o -> STM ()) m a -> m a
forall i (m :: * -> *) a (p :: [Effect]).
(Carrier m, Threaders '[ReaderThreads] m p) =>
i -> ReaderC i m a -> m a
runReader (\o
o -> do
       o
s <- TVar o -> STM o
forall a. TVar a -> STM a
readTVar TVar o
tvar
       TVar o -> o -> STM ()
forall a. TVar a -> a -> STM ()
writeTVar TVar o
tvar (o -> STM ()) -> o -> STM ()
forall a b. (a -> b) -> a -> b
$! o
s o -> o -> o
forall a. Semigroup a => a -> a -> a
<> o
o
     )
  (ReaderC (o -> STM ()) m a -> m a)
-> (InterpretPrimC
      WriterTVarH (ListenPrim o) (ReaderC (o -> STM ()) m) a
    -> ReaderC (o -> STM ()) m a)
-> InterpretPrimC
     WriterTVarH (ListenPrim o) (ReaderC (o -> STM ()) m) a
-> m a
forall b a c. Coercible b a => (b -> c) -> (a -> b) -> a -> c
.# InterpretPrimC
  WriterTVarH (ListenPrim o) (ReaderC (o -> STM ()) m) a
-> ReaderC (o -> STM ()) m a
forall h (e :: Effect) (m :: * -> *) a.
PrimHandler h e m =>
InterpretPrimC h e m a -> m a
interpretPrimViaHandler
  (InterpretPrimC
   WriterTVarH (ListenPrim o) (ReaderC (o -> STM ()) m) a
 -> m a)
-> (InterpretC
      WriterTVarH
      (Tell o)
      (InterpretPrimC
         WriterTVarH (ListenPrim o) (ReaderC (o -> STM ()) m))
      a
    -> InterpretPrimC
         WriterTVarH (ListenPrim o) (ReaderC (o -> STM ()) m) a)
-> InterpretC
     WriterTVarH
     (Tell o)
     (InterpretPrimC
        WriterTVarH (ListenPrim o) (ReaderC (o -> STM ()) m))
     a
-> m a
forall b a c. Coercible b a => (b -> c) -> (a -> b) -> a -> c
.# InterpretC
  WriterTVarH
  (Tell o)
  (InterpretPrimC
     WriterTVarH (ListenPrim o) (ReaderC (o -> STM ()) m))
  a
-> InterpretPrimC
     WriterTVarH (ListenPrim o) (ReaderC (o -> STM ()) m) a
forall h (e :: Effect) (m :: * -> *) a.
Handler h e m =>
InterpretC h e m a -> m a
interpretViaHandler
  (InterpretC
   WriterTVarH
   (Tell o)
   (InterpretPrimC
      WriterTVarH (ListenPrim o) (ReaderC (o -> STM ()) m))
   a
 -> m a)
-> (InterpretC
      WriterTVarH
      (Listen o)
      (InterpretC
         WriterTVarH
         (Tell o)
         (InterpretPrimC
            WriterTVarH (ListenPrim o) (ReaderC (o -> STM ()) m)))
      a
    -> InterpretC
         WriterTVarH
         (Tell o)
         (InterpretPrimC
            WriterTVarH (ListenPrim o) (ReaderC (o -> STM ()) m))
         a)
-> InterpretC
     WriterTVarH
     (Listen o)
     (InterpretC
        WriterTVarH
        (Tell o)
        (InterpretPrimC
           WriterTVarH (ListenPrim o) (ReaderC (o -> STM ()) m)))
     a
-> m a
forall b a c. Coercible b a => (b -> c) -> (a -> b) -> a -> c
.# InterpretC
  WriterTVarH
  (Listen o)
  (InterpretC
     WriterTVarH
     (Tell o)
     (InterpretPrimC
        WriterTVarH (ListenPrim o) (ReaderC (o -> STM ()) m)))
  a
-> InterpretC
     WriterTVarH
     (Tell o)
     (InterpretPrimC
        WriterTVarH (ListenPrim o) (ReaderC (o -> STM ()) m))
     a
forall h (e :: Effect) (m :: * -> *) a.
Handler h e m =>
InterpretC h e m a -> m a
interpretViaHandler
  (InterpretC
   WriterTVarH
   (Listen o)
   (InterpretC
      WriterTVarH
      (Tell o)
      (InterpretPrimC
         WriterTVarH (ListenPrim o) (ReaderC (o -> STM ()) m)))
   a
 -> m a)
-> (IntroUnderManyC
      '[Listen o, Tell o]
      '[ListenPrim o, Local (o -> STM ()), Ask (o -> STM ())]
      (InterpretC
         WriterTVarH
         (Listen o)
         (InterpretC
            WriterTVarH
            (Tell o)
            (InterpretPrimC
               WriterTVarH (ListenPrim o) (ReaderC (o -> STM ()) m))))
      a
    -> InterpretC
         WriterTVarH
         (Listen o)
         (InterpretC
            WriterTVarH
            (Tell o)
            (InterpretPrimC
               WriterTVarH (ListenPrim o) (ReaderC (o -> STM ()) m)))
         a)
-> IntroUnderManyC
     '[Listen o, Tell o]
     '[ListenPrim o, Local (o -> STM ()), Ask (o -> STM ())]
     (InterpretC
        WriterTVarH
        (Listen o)
        (InterpretC
           WriterTVarH
           (Tell o)
           (InterpretPrimC
              WriterTVarH (ListenPrim o) (ReaderC (o -> STM ()) m))))
     a
-> m a
forall b a c. Coercible b a => (b -> c) -> (a -> b) -> a -> c
.# IntroUnderManyC
  '[Listen o, Tell o]
  '[ListenPrim o, Local (o -> STM ()), Ask (o -> STM ())]
  (InterpretC
     WriterTVarH
     (Listen o)
     (InterpretC
        WriterTVarH
        (Tell o)
        (InterpretPrimC
           WriterTVarH (ListenPrim o) (ReaderC (o -> STM ()) m))))
  a
-> InterpretC
     WriterTVarH
     (Listen o)
     (InterpretC
        WriterTVarH
        (Tell o)
        (InterpretPrimC
           WriterTVarH (ListenPrim o) (ReaderC (o -> STM ()) m)))
     a
forall (top :: [Effect]) (new :: [Effect]) (m :: * -> *) a.
(KnownList top, KnownList new, IntroConsistent top new m) =>
IntroUnderManyC top new m a -> m a
introUnderMany
  (IntroUnderManyC
   '[Listen o, Tell o]
   '[ListenPrim o, Local (o -> STM ()), Ask (o -> STM ())]
   (InterpretC
      WriterTVarH
      (Listen o)
      (InterpretC
         WriterTVarH
         (Tell o)
         (InterpretPrimC
            WriterTVarH (ListenPrim o) (ReaderC (o -> STM ()) m))))
   a
 -> m a)
-> (ListenTVarC o m a
    -> IntroUnderManyC
         '[Listen o, Tell o]
         '[ListenPrim o, Local (o -> STM ()), Ask (o -> STM ())]
         (InterpretC
            WriterTVarH
            (Listen o)
            (InterpretC
               WriterTVarH
               (Tell o)
               (InterpretPrimC
                  WriterTVarH (ListenPrim o) (ReaderC (o -> STM ()) m))))
         a)
-> ListenTVarC o m a
-> m a
forall b a c. Coercible b a => (b -> c) -> (a -> b) -> a -> c
.# ListenTVarC o m a
-> IntroUnderManyC
     '[Listen o, Tell o]
     '[ListenPrim o, Local (o -> STM ()), Ask (o -> STM ())]
     (InterpretC
        WriterTVarH
        (Listen o)
        (InterpretC
           WriterTVarH
           (Tell o)
           (InterpretPrimC
              WriterTVarH (ListenPrim o) (ReaderC (o -> STM ()) m))))
     a
forall (ts :: [Effect]) (m :: * -> *) a.
CompositionC ts m a -> CompositionBaseM ts m a
runComposition
{-# INLINE runListenTVar #-}

-- | Run connected @'Pass' o@, @'Listen' o@ and @'Tell' o@ effects
-- -- i.e. @'Writer' o@ -- by accumulating uses of 'tell' through using atomic
-- operations in 'IO'.
--
-- @'Derivs' ('WriterTVarC' o m) = 'Pass' o ': 'Listen' o : 'Tell' o ': 'Derivs' m@
--
-- @'Prims'  ('WriterTVarC' o m) = 'WriterPrim' o ': 'Control.Effect.Type.ReaderPrim.ReaderPrim' (o -> STM ()) ': 'Prims' m@
--
-- Note that unlike 'tellToIO', this does not have a higher-rank type.
writerToIO :: forall o m a p
            . ( Monoid o
              , Eff (Embed IO) m
              , C.MonadMask m
              , Threaders '[ReaderThreads] m p
              )
           => WriterTVarC o m a
           -> m (o, a)
writerToIO :: WriterTVarC o m a -> m (o, a)
writerToIO WriterTVarC o m a
m = do
  TVar o
tvar <- IO (TVar o) -> m (TVar o)
forall (b :: * -> *) (m :: * -> *) a. Eff (Embed b) m => b a -> m a
embed (IO (TVar o) -> m (TVar o)) -> IO (TVar o) -> m (TVar o)
forall a b. (a -> b) -> a -> b
$ o -> IO (TVar o)
forall a. a -> IO (TVar a)
newTVarIO o
forall a. Monoid a => a
mempty
  a
a    <- TVar o -> WriterTVarC o m a -> m a
forall o (m :: * -> *) a (p :: [Effect]).
(Monoid o, Eff (Embed IO) m, MonadMask m,
 Threaders '[ReaderThreads] m p) =>
TVar o -> WriterTVarC o m a -> m a
runWriterTVar TVar o
tvar WriterTVarC o m a
m
  o
o    <- IO o -> m o
forall (b :: * -> *) (m :: * -> *) a. Eff (Embed b) m => b a -> m a
embed (IO o -> m o) -> IO o -> m o
forall a b. (a -> b) -> a -> b
$ TVar o -> IO o
forall a. TVar a -> IO a
readTVarIO TVar o
tvar
  (o, a) -> m (o, a)
forall (m :: * -> *) a. Monad m => a -> m a
return (o
o, a
a)
{-# INLINE writerToIO #-}

-- | Run connected @'Pass' o@, @'Listen' o@ and @'Tell' o@ effects
-- -- i.e. @'Writer' o@ -- by accumulating uses of 'tell' through using atomic
-- operations in 'IO' over a 'TVar'.
--
-- @'Derivs' ('WriterTVarC' o m) = 'Pass' o ': 'Listen' o : 'Tell' o ': 'Derivs' m@
--
-- @'Prims'  ('WriterTVarC' o m) = 'WriterPrim' o ': 'Control.Effect.Type.ReaderPrim.ReaderPrim' (o -> STM ()) ': 'Prims' m@
--
-- Note that unlike 'runTellTVar', this does not have a higher-rank type.
runWriterTVar :: forall o m a p
               . ( Monoid o
                 , Eff (Embed IO) m
                 , C.MonadMask m
                 , Threaders '[ReaderThreads] m p
                 )
              => TVar o
              -> WriterTVarC o m a
              -> m a
runWriterTVar :: TVar o -> WriterTVarC o m a -> m a
runWriterTVar TVar o
tvar =
     (o -> STM ()) -> ReaderC (o -> STM ()) m a -> m a
forall i (m :: * -> *) a (p :: [Effect]).
(Carrier m, Threaders '[ReaderThreads] m p) =>
i -> ReaderC i m a -> m a
runReader (\o
o -> do
       o
s <- TVar o -> STM o
forall a. TVar a -> STM a
readTVar TVar o
tvar
       TVar o -> o -> STM ()
forall a. TVar a -> a -> STM ()
writeTVar TVar o
tvar (o -> STM ()) -> o -> STM ()
forall a b. (a -> b) -> a -> b
$! o
s o -> o -> o
forall a. Semigroup a => a -> a -> a
<> o
o
     )
  (ReaderC (o -> STM ()) m a -> m a)
-> (InterpretPrimC
      WriterTVarH (WriterPrim o) (ReaderC (o -> STM ()) m) a
    -> ReaderC (o -> STM ()) m a)
-> InterpretPrimC
     WriterTVarH (WriterPrim o) (ReaderC (o -> STM ()) m) a
-> m a
forall b a c. Coercible b a => (b -> c) -> (a -> b) -> a -> c
.# InterpretPrimC
  WriterTVarH (WriterPrim o) (ReaderC (o -> STM ()) m) a
-> ReaderC (o -> STM ()) m a
forall h (e :: Effect) (m :: * -> *) a.
PrimHandler h e m =>
InterpretPrimC h e m a -> m a
interpretPrimViaHandler
  (InterpretPrimC
   WriterTVarH (WriterPrim o) (ReaderC (o -> STM ()) m) a
 -> m a)
-> (InterpretC
      WriterTVarH
      (ListenPrim o)
      (InterpretPrimC
         WriterTVarH (WriterPrim o) (ReaderC (o -> STM ()) m))
      a
    -> InterpretPrimC
         WriterTVarH (WriterPrim o) (ReaderC (o -> STM ()) m) a)
-> InterpretC
     WriterTVarH
     (ListenPrim o)
     (InterpretPrimC
        WriterTVarH (WriterPrim o) (ReaderC (o -> STM ()) m))
     a
-> m a
forall b a c. Coercible b a => (b -> c) -> (a -> b) -> a -> c
.# InterpretC
  WriterTVarH
  (ListenPrim o)
  (InterpretPrimC
     WriterTVarH (WriterPrim o) (ReaderC (o -> STM ()) m))
  a
-> InterpretPrimC
     WriterTVarH (WriterPrim o) (ReaderC (o -> STM ()) m) a
forall h (e :: Effect) (m :: * -> *) a.
Handler h e m =>
InterpretC h e m a -> m a
interpretViaHandler
  (InterpretC
   WriterTVarH
   (ListenPrim o)
   (InterpretPrimC
      WriterTVarH (WriterPrim o) (ReaderC (o -> STM ()) m))
   a
 -> m a)
-> (InterpretC
      WriterTVarH
      (Tell o)
      (InterpretC
         WriterTVarH
         (ListenPrim o)
         (InterpretPrimC
            WriterTVarH (WriterPrim o) (ReaderC (o -> STM ()) m)))
      a
    -> InterpretC
         WriterTVarH
         (ListenPrim o)
         (InterpretPrimC
            WriterTVarH (WriterPrim o) (ReaderC (o -> STM ()) m))
         a)
-> InterpretC
     WriterTVarH
     (Tell o)
     (InterpretC
        WriterTVarH
        (ListenPrim o)
        (InterpretPrimC
           WriterTVarH (WriterPrim o) (ReaderC (o -> STM ()) m)))
     a
-> m a
forall b a c. Coercible b a => (b -> c) -> (a -> b) -> a -> c
.# InterpretC
  WriterTVarH
  (Tell o)
  (InterpretC
     WriterTVarH
     (ListenPrim o)
     (InterpretPrimC
        WriterTVarH (WriterPrim o) (ReaderC (o -> STM ()) m)))
  a
-> InterpretC
     WriterTVarH
     (ListenPrim o)
     (InterpretPrimC
        WriterTVarH (WriterPrim o) (ReaderC (o -> STM ()) m))
     a
forall h (e :: Effect) (m :: * -> *) a.
Handler h e m =>
InterpretC h e m a -> m a
interpretViaHandler
  (InterpretC
   WriterTVarH
   (Tell o)
   (InterpretC
      WriterTVarH
      (ListenPrim o)
      (InterpretPrimC
         WriterTVarH (WriterPrim o) (ReaderC (o -> STM ()) m)))
   a
 -> m a)
-> (InterpretC
      WriterTVarH
      (Listen o)
      (InterpretC
         WriterTVarH
         (Tell o)
         (InterpretC
            WriterTVarH
            (ListenPrim o)
            (InterpretPrimC
               WriterTVarH (WriterPrim o) (ReaderC (o -> STM ()) m))))
      a
    -> InterpretC
         WriterTVarH
         (Tell o)
         (InterpretC
            WriterTVarH
            (ListenPrim o)
            (InterpretPrimC
               WriterTVarH (WriterPrim o) (ReaderC (o -> STM ()) m)))
         a)
-> InterpretC
     WriterTVarH
     (Listen o)
     (InterpretC
        WriterTVarH
        (Tell o)
        (InterpretC
           WriterTVarH
           (ListenPrim o)
           (InterpretPrimC
              WriterTVarH (WriterPrim o) (ReaderC (o -> STM ()) m))))
     a
-> m a
forall b a c. Coercible b a => (b -> c) -> (a -> b) -> a -> c
.# InterpretC
  WriterTVarH
  (Listen o)
  (InterpretC
     WriterTVarH
     (Tell o)
     (InterpretC
        WriterTVarH
        (ListenPrim o)
        (InterpretPrimC
           WriterTVarH (WriterPrim o) (ReaderC (o -> STM ()) m))))
  a
-> InterpretC
     WriterTVarH
     (Tell o)
     (InterpretC
        WriterTVarH
        (ListenPrim o)
        (InterpretPrimC
           WriterTVarH (WriterPrim o) (ReaderC (o -> STM ()) m)))
     a
forall h (e :: Effect) (m :: * -> *) a.
Handler h e m =>
InterpretC h e m a -> m a
interpretViaHandler
  (InterpretC
   WriterTVarH
   (Listen o)
   (InterpretC
      WriterTVarH
      (Tell o)
      (InterpretC
         WriterTVarH
         (ListenPrim o)
         (InterpretPrimC
            WriterTVarH (WriterPrim o) (ReaderC (o -> STM ()) m))))
   a
 -> m a)
-> (InterpretC
      WriterTVarH
      (Pass o)
      (InterpretC
         WriterTVarH
         (Listen o)
         (InterpretC
            WriterTVarH
            (Tell o)
            (InterpretC
               WriterTVarH
               (ListenPrim o)
               (InterpretPrimC
                  WriterTVarH (WriterPrim o) (ReaderC (o -> STM ()) m)))))
      a
    -> InterpretC
         WriterTVarH
         (Listen o)
         (InterpretC
            WriterTVarH
            (Tell o)
            (InterpretC
               WriterTVarH
               (ListenPrim o)
               (InterpretPrimC
                  WriterTVarH (WriterPrim o) (ReaderC (o -> STM ()) m))))
         a)
-> InterpretC
     WriterTVarH
     (Pass o)
     (InterpretC
        WriterTVarH
        (Listen o)
        (InterpretC
           WriterTVarH
           (Tell o)
           (InterpretC
              WriterTVarH
              (ListenPrim o)
              (InterpretPrimC
                 WriterTVarH (WriterPrim o) (ReaderC (o -> STM ()) m)))))
     a
-> m a
forall b a c. Coercible b a => (b -> c) -> (a -> b) -> a -> c
.# InterpretC
  WriterTVarH
  (Pass o)
  (InterpretC
     WriterTVarH
     (Listen o)
     (InterpretC
        WriterTVarH
        (Tell o)
        (InterpretC
           WriterTVarH
           (ListenPrim o)
           (InterpretPrimC
              WriterTVarH (WriterPrim o) (ReaderC (o -> STM ()) m)))))
  a
-> InterpretC
     WriterTVarH
     (Listen o)
     (InterpretC
        WriterTVarH
        (Tell o)
        (InterpretC
           WriterTVarH
           (ListenPrim o)
           (InterpretPrimC
              WriterTVarH (WriterPrim o) (ReaderC (o -> STM ()) m))))
     a
forall h (e :: Effect) (m :: * -> *) a.
Handler h e m =>
InterpretC h e m a -> m a
interpretViaHandler
  (InterpretC
   WriterTVarH
   (Pass o)
   (InterpretC
      WriterTVarH
      (Listen o)
      (InterpretC
         WriterTVarH
         (Tell o)
         (InterpretC
            WriterTVarH
            (ListenPrim o)
            (InterpretPrimC
               WriterTVarH (WriterPrim o) (ReaderC (o -> STM ()) m)))))
   a
 -> m a)
-> (IntroUnderManyC
      '[Pass o, Listen o, Tell o]
      '[ListenPrim o, WriterPrim o, Local (o -> STM ()),
        Ask (o -> STM ())]
      (InterpretC
         WriterTVarH
         (Pass o)
         (InterpretC
            WriterTVarH
            (Listen o)
            (InterpretC
               WriterTVarH
               (Tell o)
               (InterpretC
                  WriterTVarH
                  (ListenPrim o)
                  (InterpretPrimC
                     WriterTVarH (WriterPrim o) (ReaderC (o -> STM ()) m))))))
      a
    -> InterpretC
         WriterTVarH
         (Pass o)
         (InterpretC
            WriterTVarH
            (Listen o)
            (InterpretC
               WriterTVarH
               (Tell o)
               (InterpretC
                  WriterTVarH
                  (ListenPrim o)
                  (InterpretPrimC
                     WriterTVarH (WriterPrim o) (ReaderC (o -> STM ()) m)))))
         a)
-> IntroUnderManyC
     '[Pass o, Listen o, Tell o]
     '[ListenPrim o, WriterPrim o, Local (o -> STM ()),
       Ask (o -> STM ())]
     (InterpretC
        WriterTVarH
        (Pass o)
        (InterpretC
           WriterTVarH
           (Listen o)
           (InterpretC
              WriterTVarH
              (Tell o)
              (InterpretC
                 WriterTVarH
                 (ListenPrim o)
                 (InterpretPrimC
                    WriterTVarH (WriterPrim o) (ReaderC (o -> STM ()) m))))))
     a
-> m a
forall b a c. Coercible b a => (b -> c) -> (a -> b) -> a -> c
.# IntroUnderManyC
  '[Pass o, Listen o, Tell o]
  '[ListenPrim o, WriterPrim o, Local (o -> STM ()),
    Ask (o -> STM ())]
  (InterpretC
     WriterTVarH
     (Pass o)
     (InterpretC
        WriterTVarH
        (Listen o)
        (InterpretC
           WriterTVarH
           (Tell o)
           (InterpretC
              WriterTVarH
              (ListenPrim o)
              (InterpretPrimC
                 WriterTVarH (WriterPrim o) (ReaderC (o -> STM ()) m))))))
  a
-> InterpretC
     WriterTVarH
     (Pass o)
     (InterpretC
        WriterTVarH
        (Listen o)
        (InterpretC
           WriterTVarH
           (Tell o)
           (InterpretC
              WriterTVarH
              (ListenPrim o)
              (InterpretPrimC
                 WriterTVarH (WriterPrim o) (ReaderC (o -> STM ()) m)))))
     a
forall (top :: [Effect]) (new :: [Effect]) (m :: * -> *) a.
(KnownList top, KnownList new, IntroConsistent top new m) =>
IntroUnderManyC top new m a -> m a
introUnderMany
  (IntroUnderManyC
   '[Pass o, Listen o, Tell o]
   '[ListenPrim o, WriterPrim o, Local (o -> STM ()),
     Ask (o -> STM ())]
   (InterpretC
      WriterTVarH
      (Pass o)
      (InterpretC
         WriterTVarH
         (Listen o)
         (InterpretC
            WriterTVarH
            (Tell o)
            (InterpretC
               WriterTVarH
               (ListenPrim o)
               (InterpretPrimC
                  WriterTVarH (WriterPrim o) (ReaderC (o -> STM ()) m))))))
   a
 -> m a)
-> (WriterTVarC o m a
    -> IntroUnderManyC
         '[Pass o, Listen o, Tell o]
         '[ListenPrim o, WriterPrim o, Local (o -> STM ()),
           Ask (o -> STM ())]
         (InterpretC
            WriterTVarH
            (Pass o)
            (InterpretC
               WriterTVarH
               (Listen o)
               (InterpretC
                  WriterTVarH
                  (Tell o)
                  (InterpretC
                     WriterTVarH
                     (ListenPrim o)
                     (InterpretPrimC
                        WriterTVarH (WriterPrim o) (ReaderC (o -> STM ()) m))))))
         a)
-> WriterTVarC o m a
-> m a
forall b a c. Coercible b a => (b -> c) -> (a -> b) -> a -> c
.# WriterTVarC o m a
-> IntroUnderManyC
     '[Pass o, Listen o, Tell o]
     '[ListenPrim o, WriterPrim o, Local (o -> STM ()),
       Ask (o -> STM ())]
     (InterpretC
        WriterTVarH
        (Pass o)
        (InterpretC
           WriterTVarH
           (Listen o)
           (InterpretC
              WriterTVarH
              (Tell o)
              (InterpretC
                 WriterTVarH
                 (ListenPrim o)
                 (InterpretPrimC
                    WriterTVarH (WriterPrim o) (ReaderC (o -> STM ()) m))))))
     a
forall (ts :: [Effect]) (m :: * -> *) a.
CompositionC ts m a -> CompositionBaseM ts m a
runComposition
{-# INLINE runWriterTVar #-}


-- | Run a 'Tell' effect by providing an action to be executed
-- at each use of 'tell'.
--
-- This has a higher-rank type, as it makes use of 'InterpretReifiedC'.
-- __This makes 'runTellAction' very difficult to use partially applied.__
-- __In particular, it can't be composed using @'.'@.__
--
-- If performance is secondary, consider using the slower 'runTellActionSimple',
-- which doesn't have a higher-rank type.
runTellAction :: forall o m a
               . Carrier m
              => (o -> m ())
              -> InterpretReifiedC (Tell o) m a
              -> m a
runTellAction :: (o -> m ()) -> InterpretReifiedC (Tell o) m a -> m a
runTellAction o -> m ()
act = EffHandler (Tell o) m -> InterpretReifiedC (Tell o) m a -> m a
forall (e :: Effect) (m :: * -> *) a.
(RepresentationalEff e, Carrier m) =>
EffHandler e m -> InterpretReifiedC e m a -> m a
interpret (EffHandler (Tell o) m -> InterpretReifiedC (Tell o) m a -> m a)
-> EffHandler (Tell o) m -> InterpretReifiedC (Tell o) m a -> m a
forall a b. (a -> b) -> a -> b
$ \case
  Tell o -> m () -> Effly z ()
forall (b :: * -> *) (m :: * -> *) α. MonadBase b m => b α -> m α
liftBase (o -> m ()
act o
o)
{-# INLINE runTellAction #-}

-- | Run a 'Tell' effect by providing an action to be executed
-- at each use of 'tell'.
--
-- This is a less performant version of 'runTellAction' that doesn't have
-- a higher-rank type, making it much easier to use partially applied.
runTellActionSimple :: forall o m a p
                     . (Carrier m, Threaders '[ReaderThreads] m p)
                    => (o -> m ())
                    -> InterpretSimpleC (Tell o) m a
                    -> m a
runTellActionSimple :: (o -> m ()) -> InterpretSimpleC (Tell o) m a -> m a
runTellActionSimple o -> m ()
act = EffHandler (Tell o) m -> InterpretSimpleC (Tell o) m a -> m a
forall (e :: Effect) (m :: * -> *) a (p :: [Effect]).
(RepresentationalEff e, Threaders '[ReaderThreads] m p,
 Carrier m) =>
EffHandler e m -> InterpretSimpleC e m a -> m a
interpretSimple (EffHandler (Tell o) m -> InterpretSimpleC (Tell o) m a -> m a)
-> EffHandler (Tell o) m -> InterpretSimpleC (Tell o) m a -> m a
forall a b. (a -> b) -> a -> b
$ \case
  Tell o -> m () -> Effly z ()
forall (b :: * -> *) (m :: * -> *) α. MonadBase b m => b α -> m α
liftBase (o -> m ()
act o
o)
{-# INLINE runTellActionSimple #-}

data IgnoreTellH

instance Carrier m
      => Handler IgnoreTellH (Tell o) m where
  effHandler :: Tell o (Effly z) x -> Effly z x
effHandler (Tell o
_) = () -> Effly z ()
forall (f :: * -> *) a. Applicative f => a -> f a
pure ()
  {-# INLINEABLE effHandler #-}

type IgnoreTellC o = InterpretC IgnoreTellH (Tell o)

-- | Run a 'Tell' effect by ignoring it, doing no output at all.
ignoreTell :: forall o m a
            . Carrier m
           => IgnoreTellC o m a -> m a
ignoreTell :: IgnoreTellC o m a -> m a
ignoreTell = IgnoreTellC o m a -> m a
forall h (e :: Effect) (m :: * -> *) a.
Handler h e m =>
InterpretC h e m a -> m a
interpretViaHandler
{-# INLINE ignoreTell #-}