{-# LANGUAGE AllowAmbiguousTypes #-}
{-# LANGUAGE DerivingVia #-}
{-# LANGUAGE MagicHash #-}
{-# LANGUAGE RoleAnnotations #-}
{-# LANGUAGE TypeFamilies #-}
{-# LANGUAGE UnboxedTuples #-}
{-# LANGUAGE UnliftedNewtypes #-}
{-# OPTIONS_HADDOCK not-home #-}

module Bluefin.Internal where

import qualified Control.Concurrent.Async as Async
import Control.Concurrent.MVar (newEmptyMVar, putMVar, takeMVar)
import Control.Exception (throwIO, tryJust)
import qualified Control.Exception
import Control.Monad (forever)
import Control.Monad.Base (MonadBase (liftBase))
import Control.Monad.IO.Class (MonadIO, liftIO)
import Control.Monad.IO.Unlift (MonadUnliftIO, withRunInIO)
import Control.Monad.Trans.Control (MonadBaseControl, StM, liftBaseWith, restoreM)
import qualified Control.Monad.Trans.Reader as Reader
import Data.Foldable (for_)
import Data.IORef (IORef, newIORef, readIORef, writeIORef)
import Data.Kind (Type)
import qualified Data.Unique
import GHC.Exts (Proxy#, proxy#)
import System.IO.Unsafe (unsafePerformIO)
import Unsafe.Coerce (unsafeCoerce)
import Prelude hiding (drop, head, read, return)

data Effects = Union Effects Effects

-- | @type (:&) :: Effects -> Effects -> Effects@
--
-- Union of effects
infixr 9 :&

type (:&) = Union

type role Eff nominal representational

newtype Eff (es :: Effects) a = UnsafeMkEff {forall (es :: Effects) a. Eff es a -> IO a
unsafeUnEff :: IO a}
  deriving stock ((forall a b. (a -> b) -> Eff es a -> Eff es b)
-> (forall a b. a -> Eff es b -> Eff es a) -> Functor (Eff es)
forall a b. a -> Eff es b -> Eff es a
forall a b. (a -> b) -> Eff es a -> Eff es b
forall (es :: Effects) a b. a -> Eff es b -> Eff es a
forall (es :: Effects) a b. (a -> b) -> Eff es a -> Eff es b
forall (f :: * -> *).
(forall a b. (a -> b) -> f a -> f b)
-> (forall a b. a -> f b -> f a) -> Functor f
$cfmap :: forall (es :: Effects) a b. (a -> b) -> Eff es a -> Eff es b
fmap :: forall a b. (a -> b) -> Eff es a -> Eff es b
$c<$ :: forall (es :: Effects) a b. a -> Eff es b -> Eff es a
<$ :: forall a b. a -> Eff es b -> Eff es a
Functor)
  deriving newtype (Functor (Eff es)
Functor (Eff es) =>
(forall a. a -> Eff es a)
-> (forall a b. Eff es (a -> b) -> Eff es a -> Eff es b)
-> (forall a b c.
    (a -> b -> c) -> Eff es a -> Eff es b -> Eff es c)
-> (forall a b. Eff es a -> Eff es b -> Eff es b)
-> (forall a b. Eff es a -> Eff es b -> Eff es a)
-> Applicative (Eff es)
forall a. a -> Eff es a
forall a b. Eff es a -> Eff es b -> Eff es a
forall a b. Eff es a -> Eff es b -> Eff es b
forall a b. Eff es (a -> b) -> Eff es a -> Eff es b
forall a b c. (a -> b -> c) -> Eff es a -> Eff es b -> Eff es c
forall (es :: Effects). Functor (Eff es)
forall (es :: Effects) a. a -> Eff es a
forall (es :: Effects) a b. Eff es a -> Eff es b -> Eff es a
forall (es :: Effects) a b. Eff es a -> Eff es b -> Eff es b
forall (es :: Effects) a b. Eff es (a -> b) -> Eff es a -> Eff es b
forall (es :: Effects) a b c.
(a -> b -> c) -> Eff es a -> Eff es b -> Eff es c
forall (f :: * -> *).
Functor f =>
(forall a. a -> f a)
-> (forall a b. f (a -> b) -> f a -> f b)
-> (forall a b c. (a -> b -> c) -> f a -> f b -> f c)
-> (forall a b. f a -> f b -> f b)
-> (forall a b. f a -> f b -> f a)
-> Applicative f
$cpure :: forall (es :: Effects) a. a -> Eff es a
pure :: forall a. a -> Eff es a
$c<*> :: forall (es :: Effects) a b. Eff es (a -> b) -> Eff es a -> Eff es b
<*> :: forall a b. Eff es (a -> b) -> Eff es a -> Eff es b
$cliftA2 :: forall (es :: Effects) a b c.
(a -> b -> c) -> Eff es a -> Eff es b -> Eff es c
liftA2 :: forall a b c. (a -> b -> c) -> Eff es a -> Eff es b -> Eff es c
$c*> :: forall (es :: Effects) a b. Eff es a -> Eff es b -> Eff es b
*> :: forall a b. Eff es a -> Eff es b -> Eff es b
$c<* :: forall (es :: Effects) a b. Eff es a -> Eff es b -> Eff es a
<* :: forall a b. Eff es a -> Eff es b -> Eff es a
Applicative, Applicative (Eff es)
Applicative (Eff es) =>
(forall a b. Eff es a -> (a -> Eff es b) -> Eff es b)
-> (forall a b. Eff es a -> Eff es b -> Eff es b)
-> (forall a. a -> Eff es a)
-> Monad (Eff es)
forall a. a -> Eff es a
forall a b. Eff es a -> Eff es b -> Eff es b
forall a b. Eff es a -> (a -> Eff es b) -> Eff es b
forall (es :: Effects). Applicative (Eff es)
forall (es :: Effects) a. a -> Eff es a
forall (es :: Effects) a b. Eff es a -> Eff es b -> Eff es b
forall (es :: Effects) a b. Eff es a -> (a -> Eff es b) -> Eff es b
forall (m :: * -> *).
Applicative m =>
(forall a b. m a -> (a -> m b) -> m b)
-> (forall a b. m a -> m b -> m b)
-> (forall a. a -> m a)
-> Monad m
$c>>= :: forall (es :: Effects) a b. Eff es a -> (a -> Eff es b) -> Eff es b
>>= :: forall a b. Eff es a -> (a -> Eff es b) -> Eff es b
$c>> :: forall (es :: Effects) a b. Eff es a -> Eff es b -> Eff es b
>> :: forall a b. Eff es a -> Eff es b -> Eff es b
$creturn :: forall (es :: Effects) a. a -> Eff es a
return :: forall a. a -> Eff es a
Monad)

-- | Because doing 'IO' operations inside 'Eff' requires a value-level
-- argument we can't give @IO@-related instances to @Eff@ directly.
-- Instead we wrap it in @EffReader@.
newtype EffReader r es a = MkEffReader {forall r (es :: Effects) a. EffReader r es a -> r -> Eff es a
unEffReader :: r -> Eff es a}
  deriving ((forall a b. (a -> b) -> EffReader r es a -> EffReader r es b)
-> (forall a b. a -> EffReader r es b -> EffReader r es a)
-> Functor (EffReader r es)
forall a b. a -> EffReader r es b -> EffReader r es a
forall a b. (a -> b) -> EffReader r es a -> EffReader r es b
forall r (es :: Effects) a b.
a -> EffReader r es b -> EffReader r es a
forall r (es :: Effects) a b.
(a -> b) -> EffReader r es a -> EffReader r es b
forall (f :: * -> *).
(forall a b. (a -> b) -> f a -> f b)
-> (forall a b. a -> f b -> f a) -> Functor f
$cfmap :: forall r (es :: Effects) a b.
(a -> b) -> EffReader r es a -> EffReader r es b
fmap :: forall a b. (a -> b) -> EffReader r es a -> EffReader r es b
$c<$ :: forall r (es :: Effects) a b.
a -> EffReader r es b -> EffReader r es a
<$ :: forall a b. a -> EffReader r es b -> EffReader r es a
Functor, Functor (EffReader r es)
Functor (EffReader r es) =>
(forall a. a -> EffReader r es a)
-> (forall a b.
    EffReader r es (a -> b) -> EffReader r es a -> EffReader r es b)
-> (forall a b c.
    (a -> b -> c)
    -> EffReader r es a -> EffReader r es b -> EffReader r es c)
-> (forall a b.
    EffReader r es a -> EffReader r es b -> EffReader r es b)
-> (forall a b.
    EffReader r es a -> EffReader r es b -> EffReader r es a)
-> Applicative (EffReader r es)
forall a. a -> EffReader r es a
forall a b.
EffReader r es a -> EffReader r es b -> EffReader r es a
forall a b.
EffReader r es a -> EffReader r es b -> EffReader r es b
forall a b.
EffReader r es (a -> b) -> EffReader r es a -> EffReader r es b
forall a b c.
(a -> b -> c)
-> EffReader r es a -> EffReader r es b -> EffReader r es c
forall r (es :: Effects). Functor (EffReader r es)
forall r (es :: Effects) a. a -> EffReader r es a
forall r (es :: Effects) a b.
EffReader r es a -> EffReader r es b -> EffReader r es a
forall r (es :: Effects) a b.
EffReader r es a -> EffReader r es b -> EffReader r es b
forall r (es :: Effects) a b.
EffReader r es (a -> b) -> EffReader r es a -> EffReader r es b
forall r (es :: Effects) a b c.
(a -> b -> c)
-> EffReader r es a -> EffReader r es b -> EffReader r es c
forall (f :: * -> *).
Functor f =>
(forall a. a -> f a)
-> (forall a b. f (a -> b) -> f a -> f b)
-> (forall a b c. (a -> b -> c) -> f a -> f b -> f c)
-> (forall a b. f a -> f b -> f b)
-> (forall a b. f a -> f b -> f a)
-> Applicative f
$cpure :: forall r (es :: Effects) a. a -> EffReader r es a
pure :: forall a. a -> EffReader r es a
$c<*> :: forall r (es :: Effects) a b.
EffReader r es (a -> b) -> EffReader r es a -> EffReader r es b
<*> :: forall a b.
EffReader r es (a -> b) -> EffReader r es a -> EffReader r es b
$cliftA2 :: forall r (es :: Effects) a b c.
(a -> b -> c)
-> EffReader r es a -> EffReader r es b -> EffReader r es c
liftA2 :: forall a b c.
(a -> b -> c)
-> EffReader r es a -> EffReader r es b -> EffReader r es c
$c*> :: forall r (es :: Effects) a b.
EffReader r es a -> EffReader r es b -> EffReader r es b
*> :: forall a b.
EffReader r es a -> EffReader r es b -> EffReader r es b
$c<* :: forall r (es :: Effects) a b.
EffReader r es a -> EffReader r es b -> EffReader r es a
<* :: forall a b.
EffReader r es a -> EffReader r es b -> EffReader r es a
Applicative, Applicative (EffReader r es)
Applicative (EffReader r es) =>
(forall a b.
 EffReader r es a -> (a -> EffReader r es b) -> EffReader r es b)
-> (forall a b.
    EffReader r es a -> EffReader r es b -> EffReader r es b)
-> (forall a. a -> EffReader r es a)
-> Monad (EffReader r es)
forall a. a -> EffReader r es a
forall a b.
EffReader r es a -> EffReader r es b -> EffReader r es b
forall a b.
EffReader r es a -> (a -> EffReader r es b) -> EffReader r es b
forall r (es :: Effects). Applicative (EffReader r es)
forall r (es :: Effects) a. a -> EffReader r es a
forall r (es :: Effects) a b.
EffReader r es a -> EffReader r es b -> EffReader r es b
forall r (es :: Effects) a b.
EffReader r es a -> (a -> EffReader r es b) -> EffReader r es b
forall (m :: * -> *).
Applicative m =>
(forall a b. m a -> (a -> m b) -> m b)
-> (forall a b. m a -> m b -> m b)
-> (forall a. a -> m a)
-> Monad m
$c>>= :: forall r (es :: Effects) a b.
EffReader r es a -> (a -> EffReader r es b) -> EffReader r es b
>>= :: forall a b.
EffReader r es a -> (a -> EffReader r es b) -> EffReader r es b
$c>> :: forall r (es :: Effects) a b.
EffReader r es a -> EffReader r es b -> EffReader r es b
>> :: forall a b.
EffReader r es a -> EffReader r es b -> EffReader r es b
$creturn :: forall r (es :: Effects) a. a -> EffReader r es a
return :: forall a. a -> EffReader r es a
Monad) via (Reader.ReaderT r (Eff es))

instance (e :> es) => MonadIO (EffReader (IOE e) es) where
  liftIO :: forall a. IO a -> EffReader (IOE e) es a
liftIO = (IOE e -> Eff es a) -> EffReader (IOE e) es a
forall r (es :: Effects) a. (r -> Eff es a) -> EffReader r es a
MkEffReader ((IOE e -> Eff es a) -> EffReader (IOE e) es a)
-> (IO a -> IOE e -> Eff es a) -> IO a -> EffReader (IOE e) es a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (IOE e -> IO a -> Eff es a) -> IO a -> IOE e -> Eff es a
forall a b c. (a -> b -> c) -> b -> a -> c
flip IOE e -> IO a -> Eff es a
forall (e :: Effects) (es :: Effects) a.
(e :> es) =>
IOE e -> IO a -> Eff es a
effIO

effReader :: (r -> Eff es a) -> EffReader r es a
effReader :: forall r (es :: Effects) a. (r -> Eff es a) -> EffReader r es a
effReader = (r -> Eff es a) -> EffReader r es a
forall r (es :: Effects) a. (r -> Eff es a) -> EffReader r es a
MkEffReader

runEffReader :: r -> EffReader r es a -> Eff es a
runEffReader :: forall r (es :: Effects) a. r -> EffReader r es a -> Eff es a
runEffReader r
r (MkEffReader r -> Eff es a
m) = r -> Eff es a
m r
r

-- This is possibly what @withRunInIO@ should morally be.
withEffToIO ::
  (e2 :> es) =>
  -- | Continuation with the unlifting function in scope.
  ((forall r. (forall e1. IOE e1 -> Eff (e1 :& es) r) -> IO r) -> IO a) ->
  IOE e2 ->
  Eff es a
withEffToIO :: forall (e2 :: Effects) (es :: Effects) a.
(e2 :> es) =>
((forall r.
  (forall (e1 :: Effects). IOE e1 -> Eff (e1 :& es) r) -> IO r)
 -> IO a)
-> IOE e2 -> Eff es a
withEffToIO (forall r.
 (forall (e1 :: Effects). IOE e1 -> Eff (e1 :& es) r) -> IO r)
-> IO a
k IOE e2
io = IOE e2 -> IO a -> Eff es a
forall (e :: Effects) (es :: Effects) a.
(e :> es) =>
IOE e -> IO a -> Eff es a
effIO IOE e2
io ((forall r.
 (forall (e1 :: Effects). IOE e1 -> Eff (e1 :& es) r) -> IO r)
-> IO a
k (\forall (e1 :: Effects). IOE e1 -> Eff (e1 :& es) r
f -> Eff (Any :& es) r -> IO r
forall (es :: Effects) a. Eff es a -> IO a
unsafeUnEff (IOE Any -> Eff (Any :& es) r
forall (e1 :: Effects). IOE e1 -> Eff (e1 :& es) r
f IOE Any
forall (e :: Effects). IOE e
MkIOE)))

withEffToIO' ::
  (e2 :> es) =>
  -- | Continuation with the unlifting function in scope.
  IOE e2 ->
  ((forall r. (forall e1. IOE e1 -> Eff (e1 :& es) r) -> IO r) -> IO a) ->
  Eff es a
withEffToIO' :: forall (e2 :: Effects) (es :: Effects) a.
(e2 :> es) =>
IOE e2
-> ((forall r.
     (forall (e1 :: Effects). IOE e1 -> Eff (e1 :& es) r) -> IO r)
    -> IO a)
-> Eff es a
withEffToIO' IOE e2
io (forall r.
 (forall (e1 :: Effects). IOE e1 -> Eff (e1 :& es) r) -> IO r)
-> IO a
k = ((forall r.
  (forall (e1 :: Effects). IOE e1 -> Eff (e1 :& es) r) -> IO r)
 -> IO a)
-> IOE e2 -> Eff es a
forall (e2 :: Effects) (es :: Effects) a.
(e2 :> es) =>
((forall r.
  (forall (e1 :: Effects). IOE e1 -> Eff (e1 :& es) r) -> IO r)
 -> IO a)
-> IOE e2 -> Eff es a
withEffToIO (forall r.
 (forall (e1 :: Effects). IOE e1 -> Eff (e1 :& es) r) -> IO r)
-> IO a
k IOE e2
io

-- We don't try to do anything sophisticated here.  I haven't thought
-- through all the consequences.
instance (e :> es) => MonadUnliftIO (EffReader (IOE e) es) where
  withRunInIO ::
    ((forall a. EffReader (IOE e) es a -> IO a) -> IO b) ->
    EffReader (IOE e) es b
  withRunInIO :: forall b.
((forall a. EffReader (IOE e) es a -> IO a) -> IO b)
-> EffReader (IOE e) es b
withRunInIO (forall a. EffReader (IOE e) es a -> IO a) -> IO b
k =
    (IOE e -> Eff es b) -> EffReader (IOE e) es b
forall r (es :: Effects) a. (r -> Eff es a) -> EffReader r es a
MkEffReader
      ( IO b -> Eff es b
forall (es :: Effects) a. IO a -> Eff es a
UnsafeMkEff
          (IO b -> Eff es b) -> (IOE e -> IO b) -> IOE e -> Eff es b
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ReaderT (IOE e) IO b -> IOE e -> IO b
forall r (m :: * -> *) a. ReaderT r m a -> r -> m a
Reader.runReaderT
            ( ((forall a. ReaderT (IOE e) IO a -> IO a) -> IO b)
-> ReaderT (IOE e) IO b
forall b.
((forall a. ReaderT (IOE e) IO a -> IO a) -> IO b)
-> ReaderT (IOE e) IO b
forall (m :: * -> *) b.
MonadUnliftIO m =>
((forall a. m a -> IO a) -> IO b) -> m b
withRunInIO
                ( \forall a. ReaderT (IOE e) IO a -> IO a
f ->
                    (forall a. EffReader (IOE e) es a -> IO a) -> IO b
k
                      ( ReaderT (IOE e) IO a -> IO a
forall a. ReaderT (IOE e) IO a -> IO a
f
                          (ReaderT (IOE e) IO a -> IO a)
-> (EffReader (IOE e) es a -> ReaderT (IOE e) IO a)
-> EffReader (IOE e) es a
-> IO a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (IOE e -> IO a) -> ReaderT (IOE e) IO a
forall r (m :: * -> *) a. (r -> m a) -> ReaderT r m a
Reader.ReaderT
                          ((IOE e -> IO a) -> ReaderT (IOE e) IO a)
-> (EffReader (IOE e) es a -> IOE e -> IO a)
-> EffReader (IOE e) es a
-> ReaderT (IOE e) IO a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Eff es a -> IO a
forall (es :: Effects) a. Eff es a -> IO a
unsafeUnEff .)
                          ((IOE e -> Eff es a) -> IOE e -> IO a)
-> (EffReader (IOE e) es a -> IOE e -> Eff es a)
-> EffReader (IOE e) es a
-> IOE e
-> IO a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. EffReader (IOE e) es a -> IOE e -> Eff es a
forall r (es :: Effects) a. EffReader r es a -> r -> Eff es a
unEffReader
                      )
                )
            )
      )

race ::
  (e2 :> es) =>
  (forall e. IOE e -> Eff (e :& es) a) ->
  (forall e. IOE e -> Eff (e :& es) a) ->
  IOE e2 ->
  Eff es a
race :: forall (e2 :: Effects) (es :: Effects) a.
(e2 :> es) =>
(forall (e :: Effects). IOE e -> Eff (e :& es) a)
-> (forall (e :: Effects). IOE e -> Eff (e :& es) a)
-> IOE e2
-> Eff es a
race forall (e :: Effects). IOE e -> Eff (e :& es) a
x forall (e :: Effects). IOE e -> Eff (e :& es) a
y IOE e2
io = do
  Either a a
r <- IOE e2
-> ((forall {r}.
     (forall {e1 :: Effects}. IOE e1 -> Eff (e1 :& es) r) -> IO r)
    -> IO (Either a a))
-> Eff es (Either a a)
forall (e2 :: Effects) (es :: Effects) a.
(e2 :> es) =>
IOE e2
-> ((forall r.
     (forall (e1 :: Effects). IOE e1 -> Eff (e1 :& es) r) -> IO r)
    -> IO a)
-> Eff es a
withEffToIO' IOE e2
io (((forall {r}.
   (forall {e1 :: Effects}. IOE e1 -> Eff (e1 :& es) r) -> IO r)
  -> IO (Either a a))
 -> Eff es (Either a a))
-> ((forall {r}.
     (forall {e1 :: Effects}. IOE e1 -> Eff (e1 :& es) r) -> IO r)
    -> IO (Either a a))
-> Eff es (Either a a)
forall a b. (a -> b) -> a -> b
$ \forall {r}.
(forall {e1 :: Effects}. IOE e1 -> Eff (e1 :& es) r) -> IO r
toIO ->
    IO a -> IO a -> IO (Either a a)
forall a b. IO a -> IO b -> IO (Either a b)
Async.race ((forall (e :: Effects). IOE e -> Eff (e :& es) a) -> IO a
forall {r}.
(forall {e1 :: Effects}. IOE e1 -> Eff (e1 :& es) r) -> IO r
toIO IOE e1 -> Eff (e1 :& es) a
forall (e :: Effects). IOE e -> Eff (e :& es) a
x) ((forall (e :: Effects). IOE e -> Eff (e :& es) a) -> IO a
forall {r}.
(forall {e1 :: Effects}. IOE e1 -> Eff (e1 :& es) r) -> IO r
toIO IOE e1 -> Eff (e1 :& es) a
forall (e :: Effects). IOE e -> Eff (e :& es) a
y)

  a -> Eff es a
forall a. a -> Eff es a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (a -> Eff es a) -> a -> Eff es a
forall a b. (a -> b) -> a -> b
$ case Either a a
r of
    Left a
a -> a
a
    Right a
a -> a
a

-- | Connect two coroutines.  Their execution is interleaved by
-- exchanging @a@s and @b@s. When the first yields its first @a@ it
-- starts the second (which is awaiting an @a@).
connectCoroutines ::
  forall es a b r.
  (forall e. Coroutine a b e -> Eff (e :& es) r) ->
  (forall e. a -> Coroutine b a e -> Eff (e :& es) r) ->
  -- | ͘
  Eff es r
connectCoroutines :: forall (es :: Effects) a b r.
(forall (e :: Effects). Coroutine a b e -> Eff (e :& es) r)
-> (forall (e :: Effects). a -> Coroutine b a e -> Eff (e :& es) r)
-> Eff es r
connectCoroutines forall (e :: Effects). Coroutine a b e -> Eff (e :& es) r
m1 forall (e :: Effects). a -> Coroutine b a e -> Eff (e :& es) r
m2 = (forall (e :: Effects). IOE e -> Eff (e :& es) r) -> Eff es r
forall (es :: Effects) a.
(forall (e :: Effects). IOE e -> Eff (e :& es) a) -> Eff es a
unsafeProvideIO ((forall (e :: Effects). IOE e -> Eff (e :& es) r) -> Eff es r)
-> (forall (e :: Effects). IOE e -> Eff (e :& es) r) -> Eff es r
forall a b. (a -> b) -> a -> b
$ \IOE e
io -> do
  MVar a
av <- IOE e -> IO (MVar a) -> Eff (e :& es) (MVar a)
forall (e :: Effects) (es :: Effects) a.
(e :> es) =>
IOE e -> IO a -> Eff es a
effIO IOE e
io IO (MVar a)
forall a. IO (MVar a)
newEmptyMVar
  MVar b
bv <- IOE e -> IO (MVar b) -> Eff (e :& es) (MVar b)
forall (e :: Effects) (es :: Effects) a.
(e :> es) =>
IOE e -> IO a -> Eff es a
effIO IOE e
io IO (MVar b)
forall a. IO (MVar a)
newEmptyMVar

  let t1 :: forall e. IOE e -> Eff (e :& es) r
      t1 :: forall (e :: Effects). IOE e -> Eff (e :& es) r
t1 IOE e
io' = (forall (e1 :: Effects).
 Coroutine a b e1 -> Eff (e1 :& (e :& es)) r)
-> (a -> Eff (e :& es) b) -> Eff (e :& es) r
forall a b (es :: Effects) r.
(forall (e1 :: Effects). Coroutine a b e1 -> Eff (e1 :& es) r)
-> (a -> Eff es b) -> Eff es r
forEach ((Coroutine a b e1 -> Eff (e1 :& es) r)
-> Coroutine a b e1 -> Eff (e1 :& (e :& es)) r
forall (e :: Effects) (es :: Effects) t (e1 :: Effects) r.
(e :> es) =>
(t -> Eff (e1 :& e) r) -> t -> Eff (e1 :& es) r
useImplWithin Coroutine a b e1 -> Eff (e1 :& es) r
forall (e :: Effects). Coroutine a b e -> Eff (e :& es) r
m1) ((a -> Eff (e :& es) b) -> Eff (e :& es) r)
-> (a -> Eff (e :& es) b) -> Eff (e :& es) r
forall a b. (a -> b) -> a -> b
$ \a
a -> IOE e -> IO b -> Eff (e :& es) b
forall (e :: Effects) (es :: Effects) a.
(e :> es) =>
IOE e -> IO a -> Eff es a
effIO IOE e
io' (IO b -> Eff (e :& es) b) -> IO b -> Eff (e :& es) b
forall a b. (a -> b) -> a -> b
$ do
        MVar a -> a -> IO ()
forall a. MVar a -> a -> IO ()
putMVar MVar a
av a
a
        MVar b -> IO b
forall a. MVar a -> IO a
takeMVar MVar b
bv

  let t2 :: forall e. IOE e -> Eff (e :& es) r
      t2 :: forall (e :: Effects). IOE e -> Eff (e :& es) r
t2 IOE e
io' = do
        a
ainit <- IOE e -> IO a -> Eff (e :& es) a
forall (e :: Effects) (es :: Effects) a.
(e :> es) =>
IOE e -> IO a -> Eff es a
effIO IOE e
io' (MVar a -> IO a
forall a. MVar a -> IO a
takeMVar MVar a
av)
        (forall (e1 :: Effects).
 Coroutine b a e1 -> Eff (e1 :& (e :& es)) r)
-> (b -> Eff (e :& es) a) -> Eff (e :& es) r
forall a b (es :: Effects) r.
(forall (e1 :: Effects). Coroutine a b e1 -> Eff (e1 :& es) r)
-> (a -> Eff es b) -> Eff es r
forEach ((Coroutine b a e1 -> Eff (e1 :& es) r)
-> Coroutine b a e1 -> Eff (e1 :& (e :& es)) r
forall (e :: Effects) (es :: Effects) t (e1 :: Effects) r.
(e :> es) =>
(t -> Eff (e1 :& e) r) -> t -> Eff (e1 :& es) r
useImplWithin (a -> Coroutine b a e1 -> Eff (e1 :& es) r
forall (e :: Effects). a -> Coroutine b a e -> Eff (e :& es) r
m2 a
ainit)) ((b -> Eff (e :& es) a) -> Eff (e :& es) r)
-> (b -> Eff (e :& es) a) -> Eff (e :& es) r
forall a b. (a -> b) -> a -> b
$ \b
b_ -> IOE e -> IO a -> Eff (e :& es) a
forall (e :: Effects) (es :: Effects) a.
(e :> es) =>
IOE e -> IO a -> Eff es a
effIO IOE e
io' (IO a -> Eff (e :& es) a) -> IO a -> Eff (e :& es) a
forall a b. (a -> b) -> a -> b
$ do
          MVar b -> b -> IO ()
forall a. MVar a -> a -> IO ()
putMVar MVar b
bv b
b_
          MVar a -> IO a
forall a. MVar a -> IO a
takeMVar MVar a
av

  (forall (e :: Effects). IOE e -> Eff (e :& (e :& es)) r)
-> (forall (e :: Effects). IOE e -> Eff (e :& (e :& es)) r)
-> IOE e
-> Eff (e :& es) r
forall (e2 :: Effects) (es :: Effects) a.
(e2 :> es) =>
(forall (e :: Effects). IOE e -> Eff (e :& es) a)
-> (forall (e :: Effects). IOE e -> Eff (e :& es) a)
-> IOE e2
-> Eff es a
race ((IOE e -> Eff (e :& es) r) -> IOE e -> Eff (e :& (e :& es)) r
forall (e :: Effects) (es :: Effects) t (e1 :: Effects) r.
(e :> es) =>
(t -> Eff (e1 :& e) r) -> t -> Eff (e1 :& es) r
useImplWithin IOE e -> Eff (e :& es) r
forall (e :: Effects). IOE e -> Eff (e :& es) r
t1) ((IOE e -> Eff (e :& es) r) -> IOE e -> Eff (e :& (e :& es)) r
forall (e :: Effects) (es :: Effects) t (e1 :: Effects) r.
(e :> es) =>
(t -> Eff (e1 :& e) r) -> t -> Eff (e1 :& es) r
useImplWithin IOE e -> Eff (e :& es) r
forall (e :: Effects). IOE e -> Eff (e :& es) r
t2) IOE e
io

-- | Old name for 'consumeStream'.  @receiveStream@ will be deprecated
-- in a future version.
receiveStream ::
  (forall e. Consume a e -> Eff (e :& es) r) ->
  (forall e. Stream a e -> Eff (e :& es) r) ->
  Eff es r
receiveStream :: forall a (es :: Effects) r.
(forall (e :: Effects). Consume a e -> Eff (e :& es) r)
-> (forall (e :: Effects). Stream a e -> Eff (e :& es) r)
-> Eff es r
receiveStream = (forall (e :: Effects). Consume a e -> Eff (e :& es) r)
-> (forall (e :: Effects). Stream a e -> Eff (e :& es) r)
-> Eff es r
forall a (es :: Effects) r.
(forall (e :: Effects). Consume a e -> Eff (e :& es) r)
-> (forall (e :: Effects). Stream a e -> Eff (e :& es) r)
-> Eff es r
consumeStream

consumeStream ::
  -- | Each 'await' from the @Consume@ ...
  (forall e. Consume a e -> Eff (e :& es) r) ->
  -- | ... receives the value 'yield'ed from the @Stream@
  (forall e. Stream a e -> Eff (e :& es) r) ->
  Eff es r
consumeStream :: forall a (es :: Effects) r.
(forall (e :: Effects). Consume a e -> Eff (e :& es) r)
-> (forall (e :: Effects). Stream a e -> Eff (e :& es) r)
-> Eff es r
consumeStream forall (e :: Effects). Consume a e -> Eff (e :& es) r
r forall (e :: Effects). Stream a e -> Eff (e :& es) r
s = (forall (e :: Effects). Consume a e -> Eff (e :& es) r)
-> (forall (e :: Effects).
    () -> Coroutine a () e -> Eff (e :& es) r)
-> Eff es r
forall (es :: Effects) a b r.
(forall (e :: Effects). Coroutine a b e -> Eff (e :& es) r)
-> (forall (e :: Effects). a -> Coroutine b a e -> Eff (e :& es) r)
-> Eff es r
connectCoroutines Consume a e -> Eff (e :& es) r
forall (e :: Effects). Consume a e -> Eff (e :& es) r
r (\() -> Coroutine a () e -> Eff (e :& es) r
forall (e :: Effects). Stream a e -> Eff (e :& es) r
s)

zipCoroutines ::
  (e1 :> es) =>
  Coroutine (a1, a2) b e1 ->
  (forall e. Coroutine a1 b e -> Eff (e :& es) r) ->
  (forall e. Coroutine a2 b e -> Eff (e :& es) r) ->
  -- | ͘
  Eff es r
zipCoroutines :: forall (e1 :: Effects) (es :: Effects) a1 a2 b r.
(e1 :> es) =>
Coroutine (a1, a2) b e1
-> (forall (e :: Effects). Coroutine a1 b e -> Eff (e :& es) r)
-> (forall (e :: Effects). Coroutine a2 b e -> Eff (e :& es) r)
-> Eff es r
zipCoroutines Coroutine (a1, a2) b e1
c forall (e :: Effects). Coroutine a1 b e -> Eff (e :& es) r
m1 forall (e :: Effects). Coroutine a2 b e -> Eff (e :& es) r
m2 = do
  (forall (e :: Effects). Coroutine a1 b e -> Eff (e :& es) r)
-> (forall {e :: Effects}.
    a1 -> Coroutine b a1 e -> Eff (e :& es) r)
-> Eff es r
forall (es :: Effects) a b r.
(forall (e :: Effects). Coroutine a b e -> Eff (e :& es) r)
-> (forall (e :: Effects). a -> Coroutine b a e -> Eff (e :& es) r)
-> Eff es r
connectCoroutines Coroutine a1 b e -> Eff (e :& es) r
forall (e :: Effects). Coroutine a1 b e -> Eff (e :& es) r
m1 ((forall {e :: Effects}. a1 -> Coroutine b a1 e -> Eff (e :& es) r)
 -> Eff es r)
-> (forall {e :: Effects}.
    a1 -> Coroutine b a1 e -> Eff (e :& es) r)
-> Eff es r
forall a b. (a -> b) -> a -> b
$ \a1
a1 Coroutine b a1 e
c1 -> do
    (forall (e :: Effects). Coroutine a2 b e -> Eff (e :& (e :& es)) r)
-> (forall {e :: Effects}.
    a2 -> Coroutine b a2 e -> Eff (e :& (e :& es)) r)
-> Eff (e :& es) r
forall (es :: Effects) a b r.
(forall (e :: Effects). Coroutine a b e -> Eff (e :& es) r)
-> (forall (e :: Effects). a -> Coroutine b a e -> Eff (e :& es) r)
-> Eff es r
connectCoroutines ((Coroutine a2 b e -> Eff (e :& es) r)
-> Coroutine a2 b e -> Eff (e :& (e :& es)) r
forall (e :: Effects) (es :: Effects) t (e1 :: Effects) r.
(e :> es) =>
(t -> Eff (e1 :& e) r) -> t -> Eff (e1 :& es) r
useImplWithin Coroutine a2 b e -> Eff (e :& es) r
forall (e :: Effects). Coroutine a2 b e -> Eff (e :& es) r
m2) ((forall {e :: Effects}.
  a2 -> Coroutine b a2 e -> Eff (e :& (e :& es)) r)
 -> Eff (e :& es) r)
-> (forall {e :: Effects}.
    a2 -> Coroutine b a2 e -> Eff (e :& (e :& es)) r)
-> Eff (e :& es) r
forall a b. (a -> b) -> a -> b
$ \a2
a2 Coroutine b a2 e
c2 -> do
      (a1, a2)
-> (forall {e :: Effects}.
    State (a1, a2) e -> Eff (e :& (e :& (e :& es))) r)
-> Eff (e :& (e :& es)) r
forall s (es :: Effects) a.
s
-> (forall (e :: Effects). State s e -> Eff (e :& es) a)
-> Eff es a
evalState (a1
a1, a2
a2) ((forall {e :: Effects}.
  State (a1, a2) e -> Eff (e :& (e :& (e :& es))) r)
 -> Eff (e :& (e :& es)) r)
-> (forall {e :: Effects}.
    State (a1, a2) e -> Eff (e :& (e :& (e :& es))) r)
-> Eff (e :& (e :& es)) r
forall a b. (a -> b) -> a -> b
$ \State (a1, a2) e
ass -> do
        Eff (e :& (e :& (e :& es))) () -> Eff (e :& (e :& (e :& es))) r
forall (f :: * -> *) a b. Applicative f => f a -> f b
forever (Eff (e :& (e :& (e :& es))) () -> Eff (e :& (e :& (e :& es))) r)
-> Eff (e :& (e :& (e :& es))) () -> Eff (e :& (e :& (e :& es))) r
forall a b. (a -> b) -> a -> b
$ do
          (a1, a2)
as <- State (a1, a2) e -> Eff (e :& (e :& (e :& es))) (a1, a2)
forall (e :: Effects) (es :: Effects) s.
(e :> es) =>
State s e -> Eff es s
get State (a1, a2) e
ass
          b
b' <- Coroutine (a1, a2) b e1
-> (a1, a2) -> Eff (e :& (e :& (e :& es))) b
forall (e1 :: Effects) (es :: Effects) a b.
(e1 :> es) =>
Coroutine a b e1 -> a -> Eff es b
yieldCoroutine Coroutine (a1, a2) b e1
c (a1, a2)
as
          a1
a1' <- Coroutine b a1 e -> b -> Eff (e :& (e :& (e :& es))) a1
forall (e1 :: Effects) (es :: Effects) a b.
(e1 :> es) =>
Coroutine a b e1 -> a -> Eff es b
yieldCoroutine Coroutine b a1 e
c1 b
b'
          a2
a2' <- Coroutine b a2 e -> b -> Eff (e :& (e :& (e :& es))) a2
forall (e1 :: Effects) (es :: Effects) a b.
(e1 :> es) =>
Coroutine a b e1 -> a -> Eff es b
yieldCoroutine Coroutine b a2 e
c2 b
b'
          State (a1, a2) e -> (a1, a2) -> Eff (e :& (e :& (e :& es))) ()
forall (e :: Effects) (es :: Effects) s.
(e :> es) =>
State s e -> s -> Eff es ()
put State (a1, a2) e
ass (a1
a1', a2
a2')

instance (e :> es) => MonadBase IO (EffReader (IOE e) es) where
  liftBase :: forall α. IO α -> EffReader (IOE e) es α
liftBase = IO α -> EffReader (IOE e) es α
forall α. IO α -> EffReader (IOE e) es α
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO

instance (e :> es) => MonadBaseControl IO (EffReader (IOE e) es) where
  type StM (EffReader (IOE e) es) a = a
  liftBaseWith :: forall a.
(RunInBase (EffReader (IOE e) es) IO -> IO a)
-> EffReader (IOE e) es a
liftBaseWith = ((forall a. EffReader (IOE e) es a -> IO a) -> IO a)
-> EffReader (IOE e) es a
(RunInBase (EffReader (IOE e) es) IO -> IO a)
-> EffReader (IOE e) es a
forall b.
((forall a. EffReader (IOE e) es a -> IO a) -> IO b)
-> EffReader (IOE e) es b
forall (m :: * -> *) b.
MonadUnliftIO m =>
((forall a. m a -> IO a) -> IO b) -> m b
withRunInIO
  restoreM :: forall a. StM (EffReader (IOE e) es) a -> EffReader (IOE e) es a
restoreM = a -> EffReader (IOE e) es a
StM (EffReader (IOE e) es) a -> EffReader (IOE e) es a
forall a. a -> EffReader (IOE e) es a
forall (f :: * -> *) a. Applicative f => a -> f a
pure

instance (e :> es) => MonadFail (EffReader (Exception String e) es) where
  fail :: forall a. String -> EffReader (Exception String e) es a
fail = (Exception String e -> Eff es a)
-> EffReader (Exception String e) es a
forall r (es :: Effects) a. (r -> Eff es a) -> EffReader r es a
MkEffReader ((Exception String e -> Eff es a)
 -> EffReader (Exception String e) es a)
-> (String -> Exception String e -> Eff es a)
-> String
-> EffReader (Exception String e) es a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Exception String e -> String -> Eff es a)
-> String -> Exception String e -> Eff es a
forall a b c. (a -> b -> c) -> b -> a -> c
flip Exception String e -> String -> Eff es a
forall (e :: Effects) (es :: Effects) ex a.
(e :> es) =>
Exception ex e -> ex -> Eff es a
throw

hoistReader ::
  (forall b. m b -> n b) ->
  Reader.ReaderT r m a ->
  Reader.ReaderT r n a
hoistReader :: forall (m :: * -> *) (n :: * -> *) r a.
(forall b. m b -> n b) -> ReaderT r m a -> ReaderT r n a
hoistReader forall b. m b -> n b
f = (r -> n a) -> ReaderT r n a
forall r (m :: * -> *) a. (r -> m a) -> ReaderT r m a
Reader.ReaderT ((r -> n a) -> ReaderT r n a)
-> (ReaderT r m a -> r -> n a) -> ReaderT r m a -> ReaderT r n a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (\ReaderT r m a
m -> m a -> n a
forall b. m b -> n b
f (m a -> n a) -> (r -> m a) -> r -> n a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ReaderT r m a -> r -> m a
forall r (m :: * -> *) a. ReaderT r m a -> r -> m a
Reader.runReaderT ReaderT r m a
m)

-- | Run `MonadIO` operations in 'Eff'.
--
-- @
-- >>> runEff $ \\io -> withMonadIO io $ liftIO $ do
--       putStrLn "Hello world!"
-- Hello, world!
-- @

-- This is not really any better than just running the action in
-- `IO`.
withMonadIO ::
  (e :> es) =>
  IOE e ->
  -- | 'MonadIO' operation
  (forall m. (MonadIO m) => m r) ->
  -- | @MonadIO@ operation run in @Eff@
  Eff es r
withMonadIO :: forall (e :: Effects) (es :: Effects) r.
(e :> es) =>
IOE e -> (forall (m :: * -> *). MonadIO m => m r) -> Eff es r
withMonadIO IOE e
io forall (m :: * -> *). MonadIO m => m r
m = EffReader (IOE e) es r -> IOE e -> Eff es r
forall r (es :: Effects) a. EffReader r es a -> r -> Eff es a
unEffReader EffReader (IOE e) es r
forall (m :: * -> *). MonadIO m => m r
m IOE e
io

-- | Run 'MonadFail' operations in 'Eff'.
--
-- @
-- >>> runPureEff $ try $ \\e ->
--       when (2 > 1) $
--         withMonadFail e (fail "2 was bigger than 1")
-- Left "2 was bigger than 1"
-- @

-- This is not really any better than just running the action in
-- `Either String` and then applying `either (throw f) pure`.
withMonadFail ::
  (e :> es) =>
  -- | @Exception@ to @throw@ on @fail@
  Exception String e ->
  -- | 'MonadFail' operation
  (forall m. (MonadFail m) => m r) ->
  -- | @MonadFail@ operation run in @Eff@
  Eff es r
withMonadFail :: forall (e :: Effects) (es :: Effects) r.
(e :> es) =>
Exception String e
-> (forall (m :: * -> *). MonadFail m => m r) -> Eff es r
withMonadFail Exception String e
f forall (m :: * -> *). MonadFail m => m r
m = EffReader (Exception String e) es r
-> Exception String e -> Eff es r
forall r (es :: Effects) a. EffReader r es a -> r -> Eff es a
unEffReader EffReader (Exception String e) es r
forall (m :: * -> *). MonadFail m => m r
m Exception String e
f

unsafeRemoveEff :: Eff (e :& es) a -> Eff es a
unsafeRemoveEff :: forall (e :: Effects) (es :: Effects) a.
Eff (e :& es) a -> Eff es a
unsafeRemoveEff = IO a -> Eff es a
forall (es :: Effects) a. IO a -> Eff es a
UnsafeMkEff (IO a -> Eff es a)
-> (Eff (e :& es) a -> IO a) -> Eff (e :& es) a -> Eff es a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Eff (e :& es) a -> IO a
forall (es :: Effects) a. Eff es a -> IO a
unsafeUnEff

-- | Run an 'Eff' that doesn't contain any unhandled effects.
runPureEff :: (forall es. Eff es a) -> a
runPureEff :: forall a. (forall (es :: Effects). Eff es a) -> a
runPureEff forall (es :: Effects). Eff es a
e = IO a -> a
forall a. IO a -> a
unsafePerformIO (Eff Any a -> IO a
forall (es :: Effects) a. Eff es a -> IO a
unsafeUnEff Eff Any a
forall (es :: Effects). Eff es a
e)

weakenEff :: t `In` t' -> Eff t r -> Eff t' r
weakenEff :: forall (t :: Effects) (t' :: Effects) r.
In t t' -> Eff t r -> Eff t' r
weakenEff In t t'
_ = IO r -> Eff t' r
forall (es :: Effects) a. IO a -> Eff es a
UnsafeMkEff (IO r -> Eff t' r) -> (Eff t r -> IO r) -> Eff t r -> Eff t' r
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Eff t r -> IO r
forall (es :: Effects) a. Eff es a -> IO a
unsafeUnEff

insertFirst :: Eff b r -> Eff (c1 :& b) r
insertFirst :: forall (b :: Effects) r (c1 :: Effects). Eff b r -> Eff (c1 :& b) r
insertFirst = In b (c1 :& b) -> Eff b r -> Eff (c1 :& b) r
forall (t :: Effects) (t' :: Effects) r.
In t t' -> Eff t r -> Eff t' r
weakenEff (In b b -> In b (c1 :& b)
forall (a :: Effects) (b :: Effects) (c :: Effects).
In a b -> In a (c :& b)
drop ((# #) -> In b b
forall (a :: Effects). (# #) -> In a a
eq (# #)))

insertSecond :: Eff (c1 :& b) r -> Eff (c1 :& (c2 :& b)) r
insertSecond :: forall (c1 :: Effects) (b :: Effects) r (c2 :: Effects).
Eff (c1 :& b) r -> Eff (c1 :& (c2 :& b)) r
insertSecond = In (c1 :& b) (c1 :& (c2 :& b))
-> Eff (c1 :& b) r -> Eff (c1 :& (c2 :& b)) r
forall (t :: Effects) (t' :: Effects) r.
In t t' -> Eff t r -> Eff t' r
weakenEff (In b (c2 :& b) -> In (c1 :& b) (c1 :& (c2 :& b))
forall (a :: Effects) (b :: Effects) (c :: Effects).
In a b -> In (c :& a) (c :& b)
b (In b b -> In b (c2 :& b)
forall (a :: Effects) (b :: Effects) (c :: Effects).
In a b -> In a (c :& b)
drop ((# #) -> In b b
forall (a :: Effects). (# #) -> In a a
eq (# #))))

insertManySecond :: (b :> c) => Eff (c1 :& b) r -> Eff (c1 :& c) r
insertManySecond :: forall (b :: Effects) (c :: Effects) (c1 :: Effects) r.
(b :> c) =>
Eff (c1 :& b) r -> Eff (c1 :& c) r
insertManySecond = In (c1 :& b) (c1 :& c) -> Eff (c1 :& b) r -> Eff (c1 :& c) r
forall (t :: Effects) (t' :: Effects) r.
In t t' -> Eff t r -> Eff t' r
weakenEff (In c1 c1 -> In b c -> In (c1 :& b) (c1 :& c)
forall (a :: Effects) (b :: Effects) (c :: Effects) (d :: Effects).
In a b -> In c d -> In (a :& c) (b :& d)
bimap In c1 c1
forall (a :: Effects) (b :: Effects). (a :> b) => In a b
has In b c
forall (a :: Effects) (b :: Effects). (a :> b) => In a b
has)

assoc1Eff :: Eff ((a :& b) :& c) r -> Eff (a :& (b :& c)) r
assoc1Eff :: forall (a :: Effects) (b :: Effects) (c :: Effects) r.
Eff ((a :& b) :& c) r -> Eff (a :& (b :& c)) r
assoc1Eff = In ((a :& b) :& c) (a :& (b :& c))
-> Eff ((a :& b) :& c) r -> Eff (a :& (b :& c)) r
forall (t :: Effects) (t' :: Effects) r.
In t t' -> Eff t r -> Eff t' r
weakenEff ((# #) -> In ((a :& b) :& c) (a :& (b :& c))
forall (a :: Effects) (b :: Effects) (c :: Effects).
(# #) -> In ((a :& b) :& c) (a :& (b :& c))
assoc1 (# #))

pushFirst :: Eff a r -> Eff (a :& b) r
pushFirst :: forall (a :: Effects) r (b :: Effects). Eff a r -> Eff (a :& b) r
pushFirst = In a (a :& b) -> Eff a r -> Eff (a :& b) r
forall (t :: Effects) (t' :: Effects) r.
In t t' -> Eff t r -> Eff t' r
weakenEff ((# #) -> In a (a :& b)
forall (a :: Effects) (b :: Effects). (# #) -> In a (a :& b)
fstI (# #))

mergeEff :: Eff (a :& a) r -> Eff a r
mergeEff :: forall (a :: Effects) r. Eff (a :& a) r -> Eff a r
mergeEff = In (a :& a) a -> Eff (a :& a) r -> Eff a r
forall (t :: Effects) (t' :: Effects) r.
In t t' -> Eff t r -> Eff t' r
weakenEff ((# #) -> In (a :& a) a
forall (a :: Effects). (# #) -> In (a :& a) a
merge (# #))

inContext :: (e2 :> e1) => Eff (e1 :& e2) r -> Eff e1 r
inContext :: forall (e2 :: Effects) (e1 :: Effects) r.
(e2 :> e1) =>
Eff (e1 :& e2) r -> Eff e1 r
inContext = In (e1 :& e2) e1 -> Eff (e1 :& e2) r -> Eff e1 r
forall (t :: Effects) (t' :: Effects) r.
In t t' -> Eff t r -> Eff t' r
weakenEff (In e2 e1 -> In (e1 :& e2) e1
forall (e2 :: Effects) (e1 :: Effects).
In e2 e1 -> In (e1 :& e2) e1
subsume1 In e2 e1
forall (a :: Effects) (b :: Effects). (a :> b) => In a b
has)

-- | Used to define dynamic effects.
useImpl :: (e :> es) => Eff e r -> Eff es r
useImpl :: forall (e :: Effects) (es :: Effects) r.
(e :> es) =>
Eff e r -> Eff es r
useImpl = In e es -> Eff e r -> Eff es r
forall (t :: Effects) (t' :: Effects) r.
In t t' -> Eff t r -> Eff t' r
weakenEff In e es
forall (a :: Effects) (b :: Effects). (a :> b) => In a b
has

-- | Used to define handlers of compound effects.
useImplIn ::
  (e :> es) =>
  (t -> Eff (es :& e) r) ->
  t ->
  -- | ͘
  Eff es r
useImplIn :: forall (e :: Effects) (es :: Effects) t r.
(e :> es) =>
(t -> Eff (es :& e) r) -> t -> Eff es r
useImplIn t -> Eff (es :& e) r
f t
h = Eff (es :& e) r -> Eff es r
forall (e2 :: Effects) (e1 :: Effects) r.
(e2 :> e1) =>
Eff (e1 :& e2) r -> Eff e1 r
inContext (t -> Eff (es :& e) r
f t
h)

-- | Like 'useImplIn'
useImplWithin ::
  (e :> es) =>
  (t -> Eff (e1 :& e) r) ->
  t ->
  -- | ͘
  Eff (e1 :& es) r
useImplWithin :: forall (e :: Effects) (es :: Effects) t (e1 :: Effects) r.
(e :> es) =>
(t -> Eff (e1 :& e) r) -> t -> Eff (e1 :& es) r
useImplWithin t -> Eff (e1 :& e) r
k t
fsh = Eff (e1 :& e) r -> Eff (e1 :& es) r
forall (b :: Effects) (c :: Effects) (c1 :: Effects) r.
(b :> c) =>
Eff (c1 :& b) r -> Eff (c1 :& c) r
insertManySecond (t -> Eff (e1 :& e) r
k t
fsh)

-- | Handle to a capability to create strict mutable state handles
data StateSource (e :: Effects) = StateSource

-- | Handle to an exception of type @exn@
newtype Exception exn (e :: Effects) = UnsafeMkException (forall a. exn -> IO a)

-- | A handle to a strict mutable state of type @s@
newtype State s (e :: Effects) = UnsafeMkState (IORef s)

-- | A handle to a coroutine that yields values of type @a@ and then
-- expects values of type @b@.
newtype Coroutine a b (e :: Effects) = MkCoroutine (a -> Eff e b)

-- | A handle to a stream that yields values of type @a@.  It is
-- implemented as a handle to a coroutine that yields values of type
-- @a@ and then expects values of type @()@.
type Stream a = Coroutine a ()

type Consume a = Coroutine () a

-- | You can define a @Handle@ instance for your compound handles.  As
-- an example, an "application" handle with a dynamic effect for
-- database queries, a concrete effect for application state and a
-- concrete effect for a logging effect might look like this:
--
-- @
-- data Application e = MkApplication
--   { queryDatabase :: String -> Int -> Eff e [String],
--     applicationState :: State (Int, Bool) e,
--     logger :: Stream String e
--   }
-- @
--
-- To define @mapHandle@ for @Application@ you should apply
-- @mapHandle@ to all the fields that are themeselevs handles and
-- apply @useImpl@ to all the fields that are dynamic effects:
--
-- @
-- instance Handle Application where
--   mapHandle
--     MkApplication
--       { queryDatabase = q,
--         applicationState = a,
--         logger = l
--       } =
--       MkApplication
--         { queryDatabase = (fmap . fmap) useImpl q,
--           applicationState = mapHandle a,
--           logger = mapHandle l
--         }
-- @
--
-- Note that preceding @useImpl@ on the dynamic effect there is one
-- fmap per @->@ that appears in type of the dynamic effect.  That is,
-- @queryDatabase@ has type @String -> Int -> Eff e [String]@, which
-- has two @->@, so there are two @fmap@s before @useImpl@.
class Handle (h :: Effects -> Type) where
  -- | Used to create compound effects, i.e. handles that contain
  -- other handles.
  mapHandle :: (e :> es) => h e -> h es

instance Handle (State s) where
  mapHandle :: forall (e :: Effects) (es :: Effects).
(e :> es) =>
State s e -> State s es
mapHandle (UnsafeMkState IORef s
s) = IORef s -> State s es
forall s (e :: Effects). IORef s -> State s e
UnsafeMkState IORef s
s

instance Handle (Exception s) where
  mapHandle :: forall (e :: Effects) (es :: Effects).
(e :> es) =>
Exception s e -> Exception s es
mapHandle (UnsafeMkException forall a. s -> IO a
s) = (forall a. s -> IO a) -> Exception s es
forall exn (e :: Effects).
(forall a. exn -> IO a) -> Exception exn e
UnsafeMkException s -> IO a
forall a. s -> IO a
s

instance Handle (Coroutine a b) where
  mapHandle :: forall (e :: Effects) (es :: Effects).
(e :> es) =>
Coroutine a b e -> Coroutine a b es
mapHandle (MkCoroutine a -> Eff e b
f) = (a -> Eff es b) -> Coroutine a b es
forall a b (e :: Effects). (a -> Eff e b) -> Coroutine a b e
MkCoroutine ((Eff e b -> Eff es b) -> (a -> Eff e b) -> a -> Eff es b
forall a b. (a -> b) -> (a -> a) -> a -> b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap Eff e b -> Eff es b
forall (e :: Effects) (es :: Effects) r.
(e :> es) =>
Eff e r -> Eff es r
useImpl a -> Eff e b
f)

instance Handle (Writer w) where
  mapHandle :: forall (e :: Effects) (es :: Effects).
(e :> es) =>
Writer w e -> Writer w es
mapHandle (Writer Stream w e
wr) = Stream w es -> Writer w es
forall w (e :: Effects). Stream w e -> Writer w e
Writer (Stream w e -> Stream w es
forall (e :: Effects) (es :: Effects).
(e :> es) =>
Coroutine w () e -> Coroutine w () es
forall (h :: Effects -> *) (e :: Effects) (es :: Effects).
(Handle h, e :> es) =>
h e -> h es
mapHandle Stream w e
wr)

newtype In (a :: Effects) (b :: Effects) = In# (# #)

merge :: (# #) -> (a :& a) `In` a
merge :: forall (a :: Effects). (# #) -> In (a :& a) a
merge (# #) = (# #) -> In (a :& a) a
forall (a :: Effects) (b :: Effects). (# #) -> In a b
In# (# #)

eq :: (# #) -> a `In` a
eq :: forall (a :: Effects). (# #) -> In a a
eq (# #) = (# #) -> In a a
forall (a :: Effects) (b :: Effects). (# #) -> In a b
In# (# #)

fstI :: (# #) -> a `In` (a :& b)
fstI :: forall (a :: Effects) (b :: Effects). (# #) -> In a (a :& b)
fstI (# #) = (# #) -> In a (a :& b)
forall (a :: Effects) (b :: Effects). (# #) -> In a b
In# (# #)

sndI :: (# #) -> a `In` (b :& a)
sndI :: forall (a :: Effects) (b :: Effects). (# #) -> In a (b :& a)
sndI (# #) = (# #) -> In a (b :& a)
forall (a :: Effects) (b :: Effects). (# #) -> In a b
In# (# #)

cmp :: a `In` b -> b `In` c -> a `In` c
cmp :: forall (a :: Effects) (b :: Effects) (c :: Effects).
In a b -> In b c -> In a c
cmp (In# (# #)) (In# (# #)) = (# #) -> In a c
forall (a :: Effects) (b :: Effects). (# #) -> In a b
In# (# #)

bimap :: a `In` b -> c `In` d -> (a :& c) `In` (b :& d)
bimap :: forall (a :: Effects) (b :: Effects) (c :: Effects) (d :: Effects).
In a b -> In c d -> In (a :& c) (b :& d)
bimap (In# (# #)) (In# (# #)) = (# #) -> In (a :& c) (b :& d)
forall (a :: Effects) (b :: Effects). (# #) -> In a b
In# (# #)

assoc1 :: (# #) -> ((a :& b) :& c) `In` (a :& (b :& c))
assoc1 :: forall (a :: Effects) (b :: Effects) (c :: Effects).
(# #) -> In ((a :& b) :& c) (a :& (b :& c))
assoc1 (# #) = (# #) -> In ((a :& b) :& c) (a :& (b :& c))
forall (a :: Effects) (b :: Effects). (# #) -> In a b
In# (# #)

drop :: a `In` b -> a `In` (c :& b)
drop :: forall (a :: Effects) (b :: Effects) (c :: Effects).
In a b -> In a (c :& b)
drop In a b
h = In (c :& a) (c :& b) -> In a (c :& b)
forall (b :: Effects) (a :: Effects) (c :: Effects).
In (b :& a) c -> In a c
w2 (In a b -> In (c :& a) (c :& b)
forall (a :: Effects) (b :: Effects) (c :: Effects).
In a b -> In (c :& a) (c :& b)
b In a b
h)

here :: a `In` b -> (a `In` (b :& c))
here :: forall (a :: Effects) (b :: Effects) (c :: Effects).
In a b -> In a (b :& c)
here In a b
h = In (a :& c) (b :& c) -> In a (b :& c)
forall (a :: Effects) (b :: Effects) (c :: Effects).
In (a :& b) c -> In a c
w (In a b -> In (a :& c) (b :& c)
forall (a :: Effects) (b :: Effects) (c :: Effects).
In a b -> In (a :& c) (b :& c)
b2 In a b
h)

w :: (a :& b) `In` c -> (a `In` c)
w :: forall (a :: Effects) (b :: Effects) (c :: Effects).
In (a :& b) c -> In a c
w = In a (a :& b) -> In (a :& b) c -> In a c
forall (a :: Effects) (b :: Effects) (c :: Effects).
In a b -> In b c -> In a c
cmp ((# #) -> In a (a :& b)
forall (a :: Effects) (b :: Effects). (# #) -> In a (a :& b)
fstI (# #))

w2 :: (b :& a) `In` c -> (a `In` c)
w2 :: forall (b :: Effects) (a :: Effects) (c :: Effects).
In (b :& a) c -> In a c
w2 = In a (b :& a) -> In (b :& a) c -> In a c
forall (a :: Effects) (b :: Effects) (c :: Effects).
In a b -> In b c -> In a c
cmp ((# #) -> In a (b :& a)
forall (a :: Effects) (b :: Effects). (# #) -> In a (b :& a)
sndI (# #))

b2 :: (a `In` b) -> ((a :& c) `In` (b :& c))
b2 :: forall (a :: Effects) (b :: Effects) (c :: Effects).
In a b -> In (a :& c) (b :& c)
b2 In a b
h = In a b -> In c c -> In (a :& c) (b :& c)
forall (a :: Effects) (b :: Effects) (c :: Effects) (d :: Effects).
In a b -> In c d -> In (a :& c) (b :& d)
bimap In a b
h ((# #) -> In c c
forall (a :: Effects). (# #) -> In a a
eq (# #))

b :: (a `In` b) -> (c :& a) `In` (c :& b)
b :: forall (a :: Effects) (b :: Effects) (c :: Effects).
In a b -> In (c :& a) (c :& b)
b = In c c -> In a b -> In (c :& a) (c :& b)
forall (a :: Effects) (b :: Effects) (c :: Effects) (d :: Effects).
In a b -> In c d -> In (a :& c) (b :& d)
bimap ((# #) -> In c c
forall (a :: Effects). (# #) -> In a a
eq (# #))

subsume1 :: (e2 `In` e1) -> (e1 :& e2) `In` e1
subsume1 :: forall (e2 :: Effects) (e1 :: Effects).
In e2 e1 -> In (e1 :& e2) e1
subsume1 In e2 e1
i = In (e1 :& e2) (e1 :& e1) -> In (e1 :& e1) e1 -> In (e1 :& e2) e1
forall (a :: Effects) (b :: Effects) (c :: Effects).
In a b -> In b c -> In a c
cmp (In e1 e1 -> In e2 e1 -> In (e1 :& e2) (e1 :& e1)
forall (a :: Effects) (b :: Effects) (c :: Effects) (d :: Effects).
In a b -> In c d -> In (a :& c) (b :& d)
bimap ((# #) -> In e1 e1
forall (a :: Effects). (# #) -> In a a
eq (# #)) In e2 e1
i) ((# #) -> In (e1 :& e1) e1
forall (a :: Effects). (# #) -> In (a :& a) a
merge (# #))

-- | Effect subset constraint
class (es1 :: Effects) :> (es2 :: Effects)

-- | A set of effects @e@ is a subset of itself
instance {-# INCOHERENT #-} e :> e

-- | If @e@ is subset of @es@ then @e@ is a subset of a larger set, @x
-- :& es@
instance (e :> es) => e :> (x :& es)

-- Do we want this?
-- instance {-# incoherent #-} (e :> es) => (e' :& e) :> (e' :> es)

-- This seems a bit wobbly

-- | @e@ is a subset of a larger set @e :& es@
instance {-# INCOHERENT #-} e :> (e :& es)

-- |
-- @
-- >>> runPureEff $ try $ \\e -> do
--       throw e 42
--       pure "No exception thrown"
-- Left 42
-- @
--
-- @
-- >>> runPureEff $ try $ \\e -> do
--       pure "No exception thrown"
-- Right "No exception thrown"
-- @
throw ::
  (e :> es) =>
  Exception ex e ->
  -- | Value to throw
  ex ->
  Eff es a
throw :: forall (e :: Effects) (es :: Effects) ex a.
(e :> es) =>
Exception ex e -> ex -> Eff es a
throw (UnsafeMkException forall a. ex -> IO a
throw_) ex
e = IO a -> Eff es a
forall (es :: Effects) a. IO a -> Eff es a
UnsafeMkEff (ex -> IO a
forall a. ex -> IO a
throw_ ex
e)

has :: forall a b. (a :> b) => a `In` b
has :: forall (a :: Effects) (b :: Effects). (a :> b) => In a b
has = (# #) -> In a b
forall (a :: Effects) (b :: Effects). (# #) -> In a b
In# (# #)

data Dict c where
  Dict :: forall c. (c) => Dict c

-- Seems like it could be better
have :: forall a b. a `In` b -> Dict (a :> b)
have :: forall (a :: Effects) (b :: Effects). In a b -> Dict (a :> b)
have = Dict (a :> (a :& b)) -> In a b -> Dict (a :> b)
forall a b. a -> b
unsafeCoerce (forall (c :: Constraint). c => Dict c
Dict @(a :> (a :& b)))

-- |
-- @
-- >>> runPureEff $ try $ \\e -> do
--       throw e 42
--       pure "No exception thrown"
-- Left 42
-- @
try ::
  forall exn (es :: Effects) a.
  (forall e. Exception exn e -> Eff (e :& es) a) ->
  -- | @Left@ if the exception was thrown, @Right@ otherwise
  Eff es (Either exn a)
try :: forall exn (es :: Effects) a.
(forall (e :: Effects). Exception exn e -> Eff (e :& es) a)
-> Eff es (Either exn a)
try forall (e :: Effects). Exception exn e -> Eff (e :& es) a
f =
  IO (Either exn a) -> Eff es (Either exn a)
forall (es :: Effects) a. IO a -> Eff es a
UnsafeMkEff (IO (Either exn a) -> Eff es (Either exn a))
-> IO (Either exn a) -> Eff es (Either exn a)
forall a b. (a -> b) -> a -> b
$ ((forall a. exn -> IO a) -> IO a) -> IO (Either exn a)
forall e r. ((forall a. e -> IO a) -> IO r) -> IO (Either e r)
withScopedException_ (\forall a. exn -> IO a
throw_ -> Eff (Any :& es) a -> IO a
forall (es :: Effects) a. Eff es a -> IO a
unsafeUnEff (Exception exn Any -> Eff (Any :& es) a
forall (e :: Effects). Exception exn e -> Eff (e :& es) a
f ((forall a. exn -> IO a) -> Exception exn Any
forall exn (e :: Effects).
(forall a. exn -> IO a) -> Exception exn e
UnsafeMkException exn -> IO a
forall a. exn -> IO a
throw_)))

-- | 'handle', but with the argument order swapped
--
-- @
-- >>> runPureEff $ handle (pure . show) $ \\e -> do
--       throw e 42
--       pure "No exception thrown"
-- "42"
-- @
handle ::
  forall exn (es :: Effects) a.
  -- | If the exception is thrown, apply this handler
  (exn -> Eff es a) ->
  (forall e. Exception exn e -> Eff (e :& es) a) ->
  Eff es a
handle :: forall exn (es :: Effects) a.
(exn -> Eff es a)
-> (forall (e :: Effects). Exception exn e -> Eff (e :& es) a)
-> Eff es a
handle exn -> Eff es a
h forall (e :: Effects). Exception exn e -> Eff (e :& es) a
f =
  (forall (e :: Effects). Exception exn e -> Eff (e :& es) a)
-> Eff es (Either exn a)
forall exn (es :: Effects) a.
(forall (e :: Effects). Exception exn e -> Eff (e :& es) a)
-> Eff es (Either exn a)
try Exception exn e -> Eff (e :& es) a
forall (e :: Effects). Exception exn e -> Eff (e :& es) a
f Eff es (Either exn a) -> (Either exn a -> Eff es a) -> Eff es a
forall a b. Eff es a -> (a -> Eff es b) -> Eff es b
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= \case
    Left exn
e -> exn -> Eff es a
h exn
e
    Right a
a -> a -> Eff es a
forall a. a -> Eff es a
forall (f :: * -> *) a. Applicative f => a -> f a
pure a
a

catch ::
  forall exn (es :: Effects) a.
  (forall e. Exception exn e -> Eff (e :& es) a) ->
  -- | If the exception is thrown, apply this handler
  (exn -> Eff es a) ->
  Eff es a
catch :: forall exn (es :: Effects) a.
(forall (e :: Effects). Exception exn e -> Eff (e :& es) a)
-> (exn -> Eff es a) -> Eff es a
catch forall (e :: Effects). Exception exn e -> Eff (e :& es) a
f exn -> Eff es a
h = (exn -> Eff es a)
-> (forall (e :: Effects). Exception exn e -> Eff (e :& es) a)
-> Eff es a
forall exn (es :: Effects) a.
(exn -> Eff es a)
-> (forall (e :: Effects). Exception exn e -> Eff (e :& es) a)
-> Eff es a
handle exn -> Eff es a
h Exception exn e -> Eff (e :& es) a
forall (e :: Effects). Exception exn e -> Eff (e :& es) a
f

-- | @bracket acquire release body@: @acquire@ a resource, perform the
-- @body@ with it, and @release@ the resource even if @body@ threw an
-- exception.  This is essentially the same as
-- @Control.Exception.'Control.Exception.bracket'@, whose
-- documentation you can inspect for further details.
--
-- @bracket@ has a very general type that does not require @es@ to
-- contain an exception or IO effect. The reason that this is safe is:
--
--    * While @bracket@ does catch exceptions, this is unobservable,
--      since the exception is re-thrown; the cleanup action happens
--      unconditionally; and no part of it gets access to the thrown
--      exception.
--
--    * 'Eff' itself is able to guarantee that any exceptions thrown
--      in the body will be actually thrown before @bracket@
--      exits. This is inherited from the fact that @Eff@ is a wrapper
--      around 'IO'.
--
-- While it is usually the case that the cleanup action will in fact
-- want to use @IO@ effects, this is not universally true, see the
-- @polymorphicBracket@ example for an example.
bracket ::
  -- | Acquire the resource
  Eff es a ->
  -- | Release the resource
  (a -> Eff es ()) ->
  -- | Run the body
  (a -> Eff es b) ->
  Eff es b
bracket :: forall (es :: Effects) a b.
Eff es a -> (a -> Eff es ()) -> (a -> Eff es b) -> Eff es b
bracket Eff es a
before a -> Eff es ()
after a -> Eff es b
body =
  IO b -> Eff es b
forall (es :: Effects) a. IO a -> Eff es a
UnsafeMkEff (IO b -> Eff es b) -> IO b -> Eff es b
forall a b. (a -> b) -> a -> b
$
    IO a -> (a -> IO ()) -> (a -> IO b) -> IO b
forall a b c. IO a -> (a -> IO b) -> (a -> IO c) -> IO c
Control.Exception.bracket
      (Eff es a -> IO a
forall (es :: Effects) a. Eff es a -> IO a
unsafeUnEff Eff es a
before)
      (Eff es () -> IO ()
forall (es :: Effects) a. Eff es a -> IO a
unsafeUnEff (Eff es () -> IO ()) -> (a -> Eff es ()) -> a -> IO ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. a -> Eff es ()
after)
      (Eff es b -> IO b
forall (es :: Effects) a. Eff es a -> IO a
unsafeUnEff (Eff es b -> IO b) -> (a -> Eff es b) -> a -> IO b
forall b c a. (b -> c) -> (a -> b) -> a -> c
. a -> Eff es b
body)

-- |
-- @
-- >>> runPureEff $ runState 10 $ \\st -> do
--       n <- get st
--       pure (2 * n)
-- (20,10)
-- @
get ::
  (e :> es) =>
  State s e ->
  -- | The current value of the state
  Eff es s
get :: forall (e :: Effects) (es :: Effects) s.
(e :> es) =>
State s e -> Eff es s
get (UnsafeMkState IORef s
r) = IO s -> Eff es s
forall (es :: Effects) a. IO a -> Eff es a
UnsafeMkEff (IORef s -> IO s
forall a. IORef a -> IO a
readIORef IORef s
r)

-- | Set the value of the state
--
-- @
-- >>> runPureEff $ runState 10 $ \\st -> do
--       put st 30
-- ((), 30)
-- @
put ::
  (e :> es) =>
  State s e ->
  -- | The new value of the state.  The new value is forced before
  -- writing it to the state.
  s ->
  Eff es ()
put :: forall (e :: Effects) (es :: Effects) s.
(e :> es) =>
State s e -> s -> Eff es ()
put (UnsafeMkState IORef s
r) s
s = IO () -> Eff es ()
forall (es :: Effects) a. IO a -> Eff es a
UnsafeMkEff (IORef s -> s -> IO ()
forall a. IORef a -> a -> IO ()
writeIORef IORef s
r (s -> IO ()) -> s -> IO ()
forall a b. (a -> b) -> a -> b
$! s
s)

-- |
-- @
-- >>> runPureEff $ runState 10 $ \\st -> do
--       modify st (* 2)
-- ((), 20)
-- @
modify ::
  (e :> es) =>
  State s e ->
  -- | Apply this function to the state.  The new value of the state
  -- is forced before writing it to the state.
  (s -> s) ->
  Eff es ()
modify :: forall (e :: Effects) (es :: Effects) s.
(e :> es) =>
State s e -> (s -> s) -> Eff es ()
modify State s e
state s -> s
f = do
  s
s <- State s e -> Eff es s
forall (e :: Effects) (es :: Effects) s.
(e :> es) =>
State s e -> Eff es s
get State s e
state
  State s e -> s -> Eff es ()
forall (e :: Effects) (es :: Effects) s.
(e :> es) =>
State s e -> s -> Eff es ()
put State s e
state (s -> s
f s
s)

-- This is roughly how effectful does it
data MyException where
  MyException :: e -> Data.Unique.Unique -> MyException

instance Show MyException where
  show :: MyException -> String
show MyException
_ = String
"<MyException>"

instance Control.Exception.Exception MyException

withScopedException_ :: ((forall a. e -> IO a) -> IO r) -> IO (Either e r)
withScopedException_ :: forall e r. ((forall a. e -> IO a) -> IO r) -> IO (Either e r)
withScopedException_ (forall a. e -> IO a) -> IO r
f = do
  Unique
fresh <- IO Unique
Data.Unique.newUnique

  ((MyException -> Maybe e) -> IO r -> IO (Either e r))
-> IO r -> (MyException -> Maybe e) -> IO (Either e r)
forall a b c. (a -> b -> c) -> b -> a -> c
flip (MyException -> Maybe e) -> IO r -> IO (Either e r)
forall e b a.
Exception e =>
(e -> Maybe b) -> IO a -> IO (Either b a)
tryJust ((forall a. e -> IO a) -> IO r
f (\e
e -> MyException -> IO a
forall e a. Exception e => e -> IO a
throwIO (e -> Unique -> MyException
forall s1. s1 -> Unique -> MyException
MyException e
e Unique
fresh))) ((MyException -> Maybe e) -> IO (Either e r))
-> (MyException -> Maybe e) -> IO (Either e r)
forall a b. (a -> b) -> a -> b
$ \case
    MyException e
e Unique
tag ->
      -- unsafeCoerce is very unpleasant
      if Unique
tag Unique -> Unique -> Bool
forall a. Eq a => a -> a -> Bool
== Unique
fresh then e -> Maybe e
forall a. a -> Maybe a
Just (e -> e
forall a b. a -> b
unsafeCoerce e
e) else Maybe e
forall a. Maybe a
Nothing

-- |
-- @
-- 'runPureEff' $ 'withStateSource' $ \\source -> do
--   n <- 'newState' source 5
--   total <- newState source 0
--
--   'withJump' $ \\done -> forever $ do
--     n' <- 'Bluefin.State.get' n
--     'Bluefin.State.modify' total (+ n')
--     when (n' == 0) $ 'Bluefin.Jump.jumpTo' done
--     modify n (subtract 1)
--
--   get total
-- 15
-- @
withStateSource ::
  (forall e. StateSource e -> Eff (e :& es) a) ->
  -- | ͘
  Eff es a
withStateSource :: forall (es :: Effects) a.
(forall (e :: Effects). StateSource e -> Eff (e :& es) a)
-> Eff es a
withStateSource forall (e :: Effects). StateSource e -> Eff (e :& es) a
f = Eff (Any :& es) a -> Eff es a
forall (e :: Effects) (es :: Effects) a.
Eff (e :& es) a -> Eff es a
unsafeRemoveEff (StateSource Any -> Eff (Any :& es) a
forall (e :: Effects). StateSource e -> Eff (e :& es) a
f StateSource Any
forall (e :: Effects). StateSource e
StateSource)

-- |
-- @
-- runPureEff $ 'withStateSource' $ \\source -> do
--   n <- 'newState' source 5
--   total <- newState source 0
--
--   'Bluefin.Jump.withJump' $ \\done -> forever $ do
--     n' <- 'Bluefin.State.get' n
--     'Bluefin.State.modify' total (+ n')
--     when (n' == 0) $ 'Bluefin.Jump.jumpTo' done
--     modify n (subtract 1)
--
--   get total
-- 15
-- @
newState ::
  StateSource e ->
  -- | The initial value for the state handle
  s ->
  -- | A new state handle
  Eff es (State s e)
newState :: forall (e :: Effects) s (es :: Effects).
StateSource e -> s -> Eff es (State s e)
newState StateSource e
StateSource s
s = IO (State s e) -> Eff es (State s e)
forall (es :: Effects) a. IO a -> Eff es a
UnsafeMkEff ((IORef s -> State s e) -> IO (IORef s) -> IO (State s e)
forall a b. (a -> b) -> IO a -> IO b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap IORef s -> State s e
forall s (e :: Effects). IORef s -> State s e
UnsafeMkState (s -> IO (IORef s)
forall a. a -> IO (IORef a)
newIORef s
s))

-- |
-- @
-- >>> runPureEff $ runState 10 $ \\st -> do
--       n <- get st
--       pure (2 * n)
-- (20,10)
-- @
runState ::
  -- | Initial state
  s ->
  -- | Stateful computation
  (forall e. State s e -> Eff (e :& es) a) ->
  -- | Result and final state
  Eff es (a, s)
runState :: forall s (es :: Effects) a.
s
-> (forall (e :: Effects). State s e -> Eff (e :& es) a)
-> Eff es (a, s)
runState s
s forall (e :: Effects). State s e -> Eff (e :& es) a
f = do
  (forall (e :: Effects). StateSource e -> Eff (e :& es) (a, s))
-> Eff es (a, s)
forall (es :: Effects) a.
(forall (e :: Effects). StateSource e -> Eff (e :& es) a)
-> Eff es a
withStateSource ((forall (e :: Effects). StateSource e -> Eff (e :& es) (a, s))
 -> Eff es (a, s))
-> (forall (e :: Effects). StateSource e -> Eff (e :& es) (a, s))
-> Eff es (a, s)
forall a b. (a -> b) -> a -> b
$ \StateSource e
source -> do
    State s e
state <- StateSource e -> s -> Eff (e :& es) (State s e)
forall (e :: Effects) s (es :: Effects).
StateSource e -> s -> Eff es (State s e)
newState StateSource e
source s
s
    a
a <- State s e -> Eff (e :& es) a
forall (e :: Effects). State s e -> Eff (e :& es) a
f State s e
state
    s
s' <- State s e -> Eff (e :& es) s
forall (e :: Effects) (es :: Effects) s.
(e :> es) =>
State s e -> Eff es s
get State s e
state
    (a, s) -> Eff (e :& es) (a, s)
forall a. a -> Eff (e :& es) a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (a
a, s
s')

yieldCoroutine ::
  (e1 :> es) =>
  Coroutine a b e1 ->
  -- | ͘
  a ->
  Eff es b
yieldCoroutine :: forall (e1 :: Effects) (es :: Effects) a b.
(e1 :> es) =>
Coroutine a b e1 -> a -> Eff es b
yieldCoroutine (MkCoroutine a -> Eff e1 b
f) = Eff e1 b -> Eff es b
forall (e :: Effects) (es :: Effects) r.
(e :> es) =>
Eff e r -> Eff es r
useImpl (Eff e1 b -> Eff es b) -> (a -> Eff e1 b) -> a -> Eff es b
forall b c a. (b -> c) -> (a -> b) -> a -> c
. a -> Eff e1 b
f

-- |
-- @
-- >>> runPureEff $ yieldToList $ \\y -> do
--       yield y 1
--       yield y 2
--       yield y 100
-- ([1,2,100], ())
-- @
yield ::
  (e1 :> es) =>
  Stream a e1 ->
  -- | Yield this value from the stream
  a ->
  Eff es ()
yield :: forall (e1 :: Effects) (es :: Effects) a.
(e1 :> es) =>
Stream a e1 -> a -> Eff es ()
yield = Coroutine a () e1 -> a -> Eff es ()
forall (e1 :: Effects) (es :: Effects) a b.
(e1 :> es) =>
Coroutine a b e1 -> a -> Eff es b
yieldCoroutine

handleCoroutine ::
  (a -> Eff es b) ->
  (z -> Eff es r) ->
  (forall e1. Coroutine a b e1 -> Eff (e1 :& es) z) ->
  Eff es r
handleCoroutine :: forall a (es :: Effects) b z r.
(a -> Eff es b)
-> (z -> Eff es r)
-> (forall (e1 :: Effects). Coroutine a b e1 -> Eff (e1 :& es) z)
-> Eff es r
handleCoroutine a -> Eff es b
update z -> Eff es r
finish forall (e1 :: Effects). Coroutine a b e1 -> Eff (e1 :& es) z
f = do
  z
z <- (forall (e1 :: Effects). Coroutine a b e1 -> Eff (e1 :& es) z)
-> (a -> Eff es b) -> Eff es z
forall a b (es :: Effects) r.
(forall (e1 :: Effects). Coroutine a b e1 -> Eff (e1 :& es) r)
-> (a -> Eff es b) -> Eff es r
forEach Coroutine a b e1 -> Eff (e1 :& es) z
forall (e1 :: Effects). Coroutine a b e1 -> Eff (e1 :& es) z
f a -> Eff es b
update
  z -> Eff es r
finish z
z

-- |
-- @
-- >>> runPureEff $ yieldToList $ \\y -> do
--       forEach (inFoldable [0 .. 3]) $ \\i -> do
--         yield y i
--         yield y (i * 10)
-- ([0, 0, 1, 10, 2, 20, 3, 30], ())
-- @
forEach ::
  (forall e1. Coroutine a b e1 -> Eff (e1 :& es) r) ->
  -- | Apply this effectful function for each element of the coroutine
  (a -> Eff es b) ->
  Eff es r
forEach :: forall a b (es :: Effects) r.
(forall (e1 :: Effects). Coroutine a b e1 -> Eff (e1 :& es) r)
-> (a -> Eff es b) -> Eff es r
forEach forall (e1 :: Effects). Coroutine a b e1 -> Eff (e1 :& es) r
f a -> Eff es b
h = (Coroutine a b es -> Eff (es :& es) r)
-> Coroutine a b es -> Eff es r
forall (e :: Effects) (es :: Effects) t r.
(e :> es) =>
(t -> Eff (es :& e) r) -> t -> Eff es r
useImplIn Coroutine a b es -> Eff (es :& es) r
forall (e1 :: Effects). Coroutine a b e1 -> Eff (e1 :& es) r
f ((a -> Eff es b) -> Coroutine a b es
forall a b (e :: Effects). (a -> Eff e b) -> Coroutine a b e
MkCoroutine a -> Eff es b
h)

-- |
-- @
-- >>> runPureEff $ yieldToList $ inFoldable [1, 2, 100]
-- ([1, 2, 100], ())
-- @
inFoldable ::
  (Foldable t, e1 :> es) =>
  -- | Yield all these values from the stream
  t a ->
  Stream a e1 ->
  Eff es ()
inFoldable :: forall (t :: * -> *) (e1 :: Effects) (es :: Effects) a.
(Foldable t, e1 :> es) =>
t a -> Stream a e1 -> Eff es ()
inFoldable t a
t = t a -> (a -> Eff es ()) -> Eff es ()
forall (t :: * -> *) (f :: * -> *) a b.
(Foldable t, Applicative f) =>
t a -> (a -> f b) -> f ()
for_ t a
t ((a -> Eff es ()) -> Eff es ())
-> (Stream a e1 -> a -> Eff es ()) -> Stream a e1 -> Eff es ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Stream a e1 -> a -> Eff es ()
forall (e1 :: Effects) (es :: Effects) a.
(e1 :> es) =>
Stream a e1 -> a -> Eff es ()
yield

-- | Pair each element in the stream with an increasing index,
-- starting from 0.
--
-- @
-- >>> runPureEff $ yieldToList $ enumerate (inFoldable [\"A\", \"B\", \"C\"])
-- ([(0, \"A\"), (1, \"B\"), (2, \"C\")], ())
-- @
enumerate ::
  (e2 :> es) =>
  -- | ͘
  (forall e1. Stream a e1 -> Eff (e1 :& es) r) ->
  Stream (Int, a) e2 ->
  Eff es r
enumerate :: forall (e2 :: Effects) (es :: Effects) a r.
(e2 :> es) =>
(forall (e1 :: Effects). Stream a e1 -> Eff (e1 :& es) r)
-> Stream (Int, a) e2 -> Eff es r
enumerate forall (e1 :: Effects). Stream a e1 -> Eff (e1 :& es) r
s = Int
-> (forall (e1 :: Effects). Stream a e1 -> Eff (e1 :& es) r)
-> Stream (Int, a) e2
-> Eff es r
forall (e2 :: Effects) (es :: Effects) a r.
(e2 :> es) =>
Int
-> (forall (e1 :: Effects). Stream a e1 -> Eff (e1 :& es) r)
-> Stream (Int, a) e2
-> Eff es r
enumerateFrom Int
0 Stream a e1 -> Eff (e1 :& es) r
forall (e1 :: Effects). Stream a e1 -> Eff (e1 :& es) r
s

-- | Pair each element in the stream with an increasing index,
-- starting from an inital value.
--
-- @
-- >>> runPureEff $ yieldToList $ enumerateFrom1 (inFoldable [\"A\", \"B\", \"C\"])
-- ([(1, \"A\"), (2, \"B\"), (3, \"C\")], ())
-- @
enumerateFrom ::
  (e2 :> es) =>
  -- | Initial value
  Int ->
  (forall e1. Stream a e1 -> Eff (e1 :& es) r) ->
  Stream (Int, a) e2 ->
  Eff es r
enumerateFrom :: forall (e2 :: Effects) (es :: Effects) a r.
(e2 :> es) =>
Int
-> (forall (e1 :: Effects). Stream a e1 -> Eff (e1 :& es) r)
-> Stream (Int, a) e2
-> Eff es r
enumerateFrom Int
n forall (e1 :: Effects). Stream a e1 -> Eff (e1 :& es) r
ss Stream (Int, a) e2
st =
  Int
-> (forall {e :: Effects}. State Int e -> Eff (e :& es) r)
-> Eff es r
forall s (es :: Effects) a.
s
-> (forall (e :: Effects). State s e -> Eff (e :& es) a)
-> Eff es a
evalState Int
n ((forall {e :: Effects}. State Int e -> Eff (e :& es) r)
 -> Eff es r)
-> (forall {e :: Effects}. State Int e -> Eff (e :& es) r)
-> Eff es r
forall a b. (a -> b) -> a -> b
$ \State Int e
i -> (forall (e1 :: Effects).
 Coroutine a () e1 -> Eff (e1 :& (e :& es)) r)
-> (a -> Eff (e :& es) ()) -> Eff (e :& es) r
forall a b (es :: Effects) r.
(forall (e1 :: Effects). Coroutine a b e1 -> Eff (e1 :& es) r)
-> (a -> Eff es b) -> Eff es r
forEach (Eff (e1 :& es) r -> Eff (e1 :& (e :& es)) r
forall (c1 :: Effects) (b :: Effects) r (c2 :: Effects).
Eff (c1 :& b) r -> Eff (c1 :& (c2 :& b)) r
insertSecond (Eff (e1 :& es) r -> Eff (e1 :& (e :& es)) r)
-> (Coroutine a () e1 -> Eff (e1 :& es) r)
-> Coroutine a () e1
-> Eff (e1 :& (e :& es)) r
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Coroutine a () e1 -> Eff (e1 :& es) r
forall (e1 :: Effects). Stream a e1 -> Eff (e1 :& es) r
ss) ((a -> Eff (e :& es) ()) -> Eff (e :& es) r)
-> (a -> Eff (e :& es) ()) -> Eff (e :& es) r
forall a b. (a -> b) -> a -> b
$ \a
s -> do
    Int
ii <- State Int e -> Eff (e :& es) Int
forall (e :: Effects) (es :: Effects) s.
(e :> es) =>
State s e -> Eff es s
get State Int e
i
    Stream (Int, a) e2 -> (Int, a) -> Eff (e :& es) ()
forall (e1 :: Effects) (es :: Effects) a.
(e1 :> es) =>
Stream a e1 -> a -> Eff es ()
yield Stream (Int, a) e2
st (Int
ii, a
s)
    State Int e -> Int -> Eff (e :& es) ()
forall (e :: Effects) (es :: Effects) s.
(e :> es) =>
State s e -> s -> Eff es ()
put State Int e
i (Int
ii Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
1)

-- | A version of 'forEach' specialized to @Consume@.  Every time the
-- @Consume@ is used to 'await' a @b@, feed it the one created by the
-- handler.
consumeEach ::
  -- | Body
  ( forall e.
    Consume b e ->
    Eff (e :& es) r
  ) ->
  -- | Value to send to each @await@ in the body.
  Eff es b ->
  Eff es r
consumeEach :: forall b (es :: Effects) r.
(forall (e :: Effects). Consume b e -> Eff (e :& es) r)
-> Eff es b -> Eff es r
consumeEach forall (e :: Effects). Consume b e -> Eff (e :& es) r
k Eff es b
e = (forall (e :: Effects). Consume b e -> Eff (e :& es) r)
-> (() -> Eff es b) -> Eff es r
forall a b (es :: Effects) r.
(forall (e1 :: Effects). Coroutine a b e1 -> Eff (e1 :& es) r)
-> (a -> Eff es b) -> Eff es r
forEach Consume b e1 -> Eff (e1 :& es) r
forall (e :: Effects). Consume b e -> Eff (e :& es) r
k (\() -> Eff es b
e)

await :: (e :> es) => Consume a e -> Eff es a
await :: forall (e :: Effects) (es :: Effects) a.
(e :> es) =>
Consume a e -> Eff es a
await Consume a e
r = Consume a e -> () -> Eff es a
forall (e1 :: Effects) (es :: Effects) a b.
(e1 :> es) =>
Coroutine a b e1 -> a -> Eff es b
yieldCoroutine Consume a e
r ()

type EarlyReturn = Exception

-- | Run an 'Eff' action with the ability to return early to this
-- point.  In the language of exceptions, 'withEarlyReturn' installs
-- an exception handler for an exception of type @r@.
--
-- @
-- >>> runPureEff $ withEarlyReturn $ \\e -> do
--       for_ [1 .. 10] $ \\i -> do
--         when (i >= 5) $
--           returnEarly e ("Returned early with " ++ show i)
--       pure "End of loop"
-- "Returned early with 5"
-- @
withEarlyReturn ::
  (forall e. EarlyReturn r e -> Eff (e :& es) r) ->
  -- | ͘
  Eff es r
withEarlyReturn :: forall r (es :: Effects).
(forall (e :: Effects). EarlyReturn r e -> Eff (e :& es) r)
-> Eff es r
withEarlyReturn = (r -> Eff es r)
-> (forall (e :: Effects). EarlyReturn r e -> Eff (e :& es) r)
-> Eff es r
forall exn (es :: Effects) a.
(exn -> Eff es a)
-> (forall (e :: Effects). Exception exn e -> Eff (e :& es) a)
-> Eff es a
handle r -> Eff es r
forall a. a -> Eff es a
forall (f :: * -> *) a. Applicative f => a -> f a
pure

-- |
-- @
-- >>> runPureEff $ withEarlyReturn $ \\e -> do
--       for_ [1 .. 10] $ \\i -> do
--         when (i >= 5) $
--           returnEarly e ("Returned early with " ++ show i)
--       pure "End of loop"
-- "Returned early with 5"
-- @
returnEarly ::
  (e :> es) =>
  EarlyReturn r e ->
  -- | Return early to the handler, with this value.
  r ->
  Eff es a
returnEarly :: forall (e :: Effects) (es :: Effects) ex a.
(e :> es) =>
Exception ex e -> ex -> Eff es a
returnEarly = Exception r e -> r -> Eff es a
forall (e :: Effects) (es :: Effects) ex a.
(e :> es) =>
Exception ex e -> ex -> Eff es a
throw

-- |
-- @
-- >>> runPureEff $ evalState 10 $ \\st -> do
--       n <- get st
--       pure (2 * n)
-- 20
-- @
evalState ::
  -- | Initial state
  s ->
  -- | Stateful computation
  (forall e. State s e -> Eff (e :& es) a) ->
  -- | Result
  Eff es a
evalState :: forall s (es :: Effects) a.
s
-> (forall (e :: Effects). State s e -> Eff (e :& es) a)
-> Eff es a
evalState s
s forall (e :: Effects). State s e -> Eff (e :& es) a
f = ((a, s) -> a) -> Eff es (a, s) -> Eff es a
forall a b. (a -> b) -> Eff es a -> Eff es b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (a, s) -> a
forall a b. (a, b) -> a
fst (s
-> (forall (e :: Effects). State s e -> Eff (e :& es) a)
-> Eff es (a, s)
forall s (es :: Effects) a.
s
-> (forall (e :: Effects). State s e -> Eff (e :& es) a)
-> Eff es (a, s)
runState s
s State s e -> Eff (e :& es) a
forall (e :: Effects). State s e -> Eff (e :& es) a
f)

-- |
-- @
-- >>> runPureEff $ withState 10 $ \\st -> do
--       n <- get st
--       pure (\s -> (2 * n, s))
-- (20,10)
-- @
withState ::
  -- | Initial state
  s ->
  -- | Stateful computation
  (forall st. State s st -> Eff (st :& es) (s -> a)) ->
  -- | Result
  Eff es a
withState :: forall s (es :: Effects) a.
s
-> (forall (st :: Effects). State s st -> Eff (st :& es) (s -> a))
-> Eff es a
withState s
s forall (st :: Effects). State s st -> Eff (st :& es) (s -> a)
f = do
  (s -> a
g, s
s') <- s
-> (forall (st :: Effects). State s st -> Eff (st :& es) (s -> a))
-> Eff es (s -> a, s)
forall s (es :: Effects) a.
s
-> (forall (e :: Effects). State s e -> Eff (e :& es) a)
-> Eff es (a, s)
runState s
s State s e -> Eff (e :& es) (s -> a)
forall (st :: Effects). State s st -> Eff (st :& es) (s -> a)
f
  a -> Eff es a
forall a. a -> Eff es a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (s -> a
g s
s')

data Compound e1 e2 ss where
  Compound ::
    Proxy# s1 ->
    Proxy# s2 ->
    e1 s1 ->
    e2 s2 ->
    Compound e1 e2 (s1 :& s2)

compound ::
  h1 e1 ->
  -- | ͘
  h2 e2 ->
  Compound h1 h2 (e1 :& e2)
compound :: forall (h1 :: Effects -> *) (e1 :: Effects) (h2 :: Effects -> *)
       (e2 :: Effects).
h1 e1 -> h2 e2 -> Compound h1 h2 (e1 :& e2)
compound = Proxy# e1
-> Proxy# e2 -> h1 e1 -> h2 e2 -> Compound h1 h2 (e1 :& e2)
forall (s1 :: Effects) (s2 :: Effects) (e1 :: Effects -> *)
       (e2 :: Effects -> *).
Proxy# s1
-> Proxy# s2 -> e1 s1 -> e2 s2 -> Compound e1 e2 (s1 :& s2)
Compound Proxy# e1
forall {k} (a :: k). Proxy# a
proxy# Proxy# e2
forall {k} (a :: k). Proxy# a
proxy#

inComp :: forall a b c r. (a :> b) => (b :> c) => ((a :> c) => r) -> r
inComp :: forall (a :: Effects) (b :: Effects) (c :: Effects) r.
(a :> b, b :> c) =>
((a :> c) => r) -> r
inComp (a :> c) => r
k = case In a c -> Dict (a :> c)
forall (a :: Effects) (b :: Effects). In a b -> Dict (a :> b)
have (In a b -> In b c -> In a c
forall (a :: Effects) (b :: Effects) (c :: Effects).
In a b -> In b c -> In a c
cmp (forall (a :: Effects) (b :: Effects). (a :> b) => In a b
has @a @b) (forall (a :: Effects) (b :: Effects). (a :> b) => In a b
has @b @c)) of Dict (a :> c)
Dict -> r
(a :> c) => r
k

withCompound ::
  forall h1 h2 e es r.
  (e :> es) =>
  Compound h1 h2 e ->
  -- | ͘
  (forall e1 e2. (e1 :> es, e2 :> es) => h1 e1 -> h2 e2 -> Eff es r) ->
  Eff es r
withCompound :: forall (h1 :: Effects -> *) (h2 :: Effects -> *) (e :: Effects)
       (es :: Effects) r.
(e :> es) =>
Compound h1 h2 e
-> (forall (e1 :: Effects) (e2 :: Effects).
    (e1 :> es, e2 :> es) =>
    h1 e1 -> h2 e2 -> Eff es r)
-> Eff es r
withCompound Compound h1 h2 e
c forall (e1 :: Effects) (e2 :: Effects).
(e1 :> es, e2 :> es) =>
h1 e1 -> h2 e2 -> Eff es r
f =
  case Compound h1 h2 e
c of
    Compound (Proxy# s1
_ :: Proxy# st) (Proxy# s2
_ :: Proxy# st') h1 s1
h h2 s2
i ->
      forall (a :: Effects) (b :: Effects) (c :: Effects) r.
(a :> b, b :> c) =>
((a :> c) => r) -> r
inComp @st @e @es (forall (a :: Effects) (b :: Effects) (c :: Effects) r.
(a :> b, b :> c) =>
((a :> c) => r) -> r
inComp @st' @e @es (h1 s1 -> h2 s2 -> Eff es r
forall (e1 :: Effects) (e2 :: Effects).
(e1 :> es, e2 :> es) =>
h1 e1 -> h2 e2 -> Eff es r
f h1 s1
h h2 s2
i))

withC1 ::
  forall e1 e2 ss es r.
  (ss :> es) =>
  Compound e1 e2 ss ->
  (forall st. (st :> es) => e1 st -> Eff es r) ->
  Eff es r
withC1 :: forall (e1 :: Effects -> *) (e2 :: Effects -> *) (ss :: Effects)
       (es :: Effects) r.
(ss :> es) =>
Compound e1 e2 ss
-> (forall (st :: Effects). (st :> es) => e1 st -> Eff es r)
-> Eff es r
withC1 Compound e1 e2 ss
c forall (st :: Effects). (st :> es) => e1 st -> Eff es r
f = Compound e1 e2 ss
-> (forall (e1 :: Effects) (e2 :: Effects).
    (e1 :> es, e2 :> es) =>
    e1 e1 -> e2 e2 -> Eff es r)
-> Eff es r
forall (h1 :: Effects -> *) (h2 :: Effects -> *) (e :: Effects)
       (es :: Effects) r.
(e :> es) =>
Compound h1 h2 e
-> (forall (e1 :: Effects) (e2 :: Effects).
    (e1 :> es, e2 :> es) =>
    h1 e1 -> h2 e2 -> Eff es r)
-> Eff es r
withCompound Compound e1 e2 ss
c (\e1 e1
h e2 e2
_ -> e1 e1 -> Eff es r
forall (st :: Effects). (st :> es) => e1 st -> Eff es r
f e1 e1
h)

withC2 ::
  forall e1 e2 ss es r.
  (ss :> es) =>
  Compound e1 e2 ss ->
  (forall st. (st :> es) => e2 st -> Eff es r) ->
  Eff es r
withC2 :: forall (e1 :: Effects -> *) (e2 :: Effects -> *) (ss :: Effects)
       (es :: Effects) r.
(ss :> es) =>
Compound e1 e2 ss
-> (forall (st :: Effects). (st :> es) => e2 st -> Eff es r)
-> Eff es r
withC2 Compound e1 e2 ss
c forall (st :: Effects). (st :> es) => e2 st -> Eff es r
f = Compound e1 e2 ss
-> (forall (e1 :: Effects) (e2 :: Effects).
    (e1 :> es, e2 :> es) =>
    e1 e1 -> e2 e2 -> Eff es r)
-> Eff es r
forall (h1 :: Effects -> *) (h2 :: Effects -> *) (e :: Effects)
       (es :: Effects) r.
(e :> es) =>
Compound h1 h2 e
-> (forall (e1 :: Effects) (e2 :: Effects).
    (e1 :> es, e2 :> es) =>
    h1 e1 -> h2 e2 -> Eff es r)
-> Eff es r
withCompound Compound e1 e2 ss
c (\e1 e1
_ e2 e2
i -> e2 e2 -> Eff es r
forall (st :: Effects). (st :> es) => e2 st -> Eff es r
f e2 e2
i)

putC :: forall ss es e. (ss :> es) => Compound e (State Int) ss -> Int -> Eff es ()
putC :: forall (ss :: Effects) (es :: Effects) (e :: Effects -> *).
(ss :> es) =>
Compound e (State Int) ss -> Int -> Eff es ()
putC Compound e (State Int) ss
c Int
i = Compound e (State Int) ss
-> (forall (st :: Effects).
    (st :> es) =>
    State Int st -> Eff es ())
-> Eff es ()
forall (e1 :: Effects -> *) (e2 :: Effects -> *) (ss :: Effects)
       (es :: Effects) r.
(ss :> es) =>
Compound e1 e2 ss
-> (forall (st :: Effects). (st :> es) => e2 st -> Eff es r)
-> Eff es r
withC2 Compound e (State Int) ss
c (\State Int st
h -> State Int st -> Int -> Eff es ()
forall (e :: Effects) (es :: Effects) s.
(e :> es) =>
State s e -> s -> Eff es ()
put State Int st
h Int
i)

getC :: forall ss es e. (ss :> es) => Compound e (State Int) ss -> Eff es Int
getC :: forall (ss :: Effects) (es :: Effects) (e :: Effects -> *).
(ss :> es) =>
Compound e (State Int) ss -> Eff es Int
getC Compound e (State Int) ss
c = Compound e (State Int) ss
-> (forall (st :: Effects).
    (st :> es) =>
    State Int st -> Eff es Int)
-> Eff es Int
forall (e1 :: Effects -> *) (e2 :: Effects -> *) (ss :: Effects)
       (es :: Effects) r.
(ss :> es) =>
Compound e1 e2 ss
-> (forall (st :: Effects). (st :> es) => e2 st -> Eff es r)
-> Eff es r
withC2 Compound e (State Int) ss
c (\State Int st
h -> State Int st -> Eff es Int
forall (e :: Effects) (es :: Effects) s.
(e :> es) =>
State s e -> Eff es s
get State Int st
h)

-- TODO: Make this (s1 :> es, s2 :> es), like withC
runCompound ::
  e1 s1 ->
  -- | ͘
  e2 s2 ->
  (forall es'. Compound e1 e2 es' -> Eff (es' :& es) r) ->
  Eff (s1 :& (s2 :& es)) r
runCompound :: forall (e1 :: Effects -> *) (s1 :: Effects) (e2 :: Effects -> *)
       (s2 :: Effects) (es :: Effects) r.
e1 s1
-> e2 s2
-> (forall (es' :: Effects).
    Compound e1 e2 es' -> Eff (es' :& es) r)
-> Eff (s1 :& (s2 :& es)) r
runCompound e1 s1
e1 e2 s2
e2 forall (es' :: Effects). Compound e1 e2 es' -> Eff (es' :& es) r
k = Eff ((s1 :& s2) :& es) r -> Eff (s1 :& (s2 :& es)) r
forall (a :: Effects) (b :: Effects) (c :: Effects) r.
Eff ((a :& b) :& c) r -> Eff (a :& (b :& c)) r
assoc1Eff (Compound e1 e2 (s1 :& s2) -> Eff ((s1 :& s2) :& es) r
forall (es' :: Effects). Compound e1 e2 es' -> Eff (es' :& es) r
k (e1 s1 -> e2 s2 -> Compound e1 e2 (s1 :& s2)
forall (h1 :: Effects -> *) (e1 :: Effects) (h2 :: Effects -> *)
       (e2 :: Effects).
h1 e1 -> h2 e2 -> Compound h1 h2 (e1 :& e2)
compound e1 s1
e1 e2 s2
e2))

-- |
-- @
-- >>> runPureEff $ yieldToList $ \\y -> do
--       yield y 1
--       yield y 2
--       yield y 100
-- ([1,2,100], ())
-- @
yieldToList ::
  (forall e1. Stream a e1 -> Eff (e1 :& es) r) ->
  -- | Yielded elements and final result
  Eff es ([a], r)
yieldToList :: forall a (es :: Effects) r.
(forall (e1 :: Effects). Stream a e1 -> Eff (e1 :& es) r)
-> Eff es ([a], r)
yieldToList forall (e1 :: Effects). Stream a e1 -> Eff (e1 :& es) r
f = do
  ([a]
as, r
r) <- (forall (e1 :: Effects). Stream a e1 -> Eff (e1 :& es) r)
-> Eff es ([a], r)
forall a (es :: Effects) r.
(forall (e1 :: Effects). Stream a e1 -> Eff (e1 :& es) r)
-> Eff es ([a], r)
yieldToReverseList Stream a e -> Eff (e :& es) r
forall (e1 :: Effects). Stream a e1 -> Eff (e1 :& es) r
f
  ([a], r) -> Eff es ([a], r)
forall a. a -> Eff es a
forall (f :: * -> *) a. Applicative f => a -> f a
pure ([a] -> [a]
forall a. [a] -> [a]
reverse [a]
as, r
r)

-- |
-- @
-- >>> runPureEff $ withYieldToList $ \\y -> do
--   yield y 1
--   yield y 2
--   yield y 100
--   pure length
-- 3
-- @
withYieldToList ::
  -- | Stream computation
  (forall e. Stream a e -> Eff (e :& es) ([a] -> r)) ->
  -- | Result
  Eff es r
withYieldToList :: forall a (es :: Effects) r.
(forall (e :: Effects). Stream a e -> Eff (e :& es) ([a] -> r))
-> Eff es r
withYieldToList forall (e :: Effects). Stream a e -> Eff (e :& es) ([a] -> r)
f = do
  ([a]
l, [a] -> r
g) <- (forall (e :: Effects). Stream a e -> Eff (e :& es) ([a] -> r))
-> Eff es ([a], [a] -> r)
forall a (es :: Effects) r.
(forall (e1 :: Effects). Stream a e1 -> Eff (e1 :& es) r)
-> Eff es ([a], r)
yieldToList Stream a e1 -> Eff (e1 :& es) ([a] -> r)
forall (e :: Effects). Stream a e -> Eff (e :& es) ([a] -> r)
f
  r -> Eff es r
forall a. a -> Eff es a
forall (f :: * -> *) a. Applicative f => a -> f a
pure ([a] -> r
g [a]
l)

-- | This is more efficient than 'yieldToList' because it gathers the
-- elements into a stack in reverse order. @yieldToList@ then reverses
-- that stack.
--
-- @
-- >>> runPureEff $ yieldToReverseList $ \\y -> do
--       yield y 1
--       yield y 2
--       yield y 100
-- ([100,2,1], ())
-- @
yieldToReverseList ::
  (forall e. Stream a e -> Eff (e :& es) r) ->
  -- | Yielded elements in reverse order, and final result
  Eff es ([a], r)
yieldToReverseList :: forall a (es :: Effects) r.
(forall (e1 :: Effects). Stream a e1 -> Eff (e1 :& es) r)
-> Eff es ([a], r)
yieldToReverseList forall (e :: Effects). Stream a e -> Eff (e :& es) r
f = do
  [a]
-> (forall {e :: Effects}. State [a] e -> Eff (e :& es) ([a], r))
-> Eff es ([a], r)
forall s (es :: Effects) a.
s
-> (forall (e :: Effects). State s e -> Eff (e :& es) a)
-> Eff es a
evalState [] ((forall {e :: Effects}. State [a] e -> Eff (e :& es) ([a], r))
 -> Eff es ([a], r))
-> (forall {e :: Effects}. State [a] e -> Eff (e :& es) ([a], r))
-> Eff es ([a], r)
forall a b. (a -> b) -> a -> b
$ \(State [a] e
s :: State lo st) -> do
    r
r <- (forall (e1 :: Effects).
 Coroutine a () e1 -> Eff (e1 :& (e :& es)) r)
-> (a -> Eff (e :& es) ()) -> Eff (e :& es) r
forall a b (es :: Effects) r.
(forall (e1 :: Effects). Coroutine a b e1 -> Eff (e1 :& es) r)
-> (a -> Eff es b) -> Eff es r
forEach (Eff (e1 :& es) r -> Eff (e1 :& (e :& es)) r
forall (c1 :: Effects) (b :: Effects) r (c2 :: Effects).
Eff (c1 :& b) r -> Eff (c1 :& (c2 :& b)) r
insertSecond (Eff (e1 :& es) r -> Eff (e1 :& (e :& es)) r)
-> (Coroutine a () e1 -> Eff (e1 :& es) r)
-> Coroutine a () e1
-> Eff (e1 :& (e :& es)) r
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Coroutine a () e1 -> Eff (e1 :& es) r
forall (e :: Effects). Stream a e -> Eff (e :& es) r
f) ((a -> Eff (e :& es) ()) -> Eff (e :& es) r)
-> (a -> Eff (e :& es) ()) -> Eff (e :& es) r
forall a b. (a -> b) -> a -> b
$ \a
i ->
      State [a] e -> ([a] -> [a]) -> Eff (e :& es) ()
forall (e :: Effects) (es :: Effects) s.
(e :> es) =>
State s e -> (s -> s) -> Eff es ()
modify State [a] e
s (a
i :)
    [a]
as <- State [a] e -> Eff (e :& es) [a]
forall (e :: Effects) (es :: Effects) s.
(e :> es) =>
State s e -> Eff es s
get State [a] e
s
    ([a], r) -> Eff (e :& es) ([a], r)
forall a. a -> Eff (e :& es) a
forall (f :: * -> *) a. Applicative f => a -> f a
pure ([a]
as, r
r)

mapStream ::
  (e2 :> es) =>
  -- | Apply this function to all elements of the input stream.
  (a -> b) ->
  -- | Input stream
  (forall e1. Stream a e1 -> Eff (e1 :& es) r) ->
  Stream b e2 ->
  Eff es r
mapStream :: forall (e2 :: Effects) (es :: Effects) a b r.
(e2 :> es) =>
(a -> b)
-> (forall (e1 :: Effects). Stream a e1 -> Eff (e1 :& es) r)
-> Stream b e2
-> Eff es r
mapStream a -> b
f = (a -> Maybe b)
-> (forall (e1 :: Effects). Stream a e1 -> Eff (e1 :& es) r)
-> Stream b e2
-> Eff es r
forall (e2 :: Effects) (es :: Effects) a b r.
(e2 :> es) =>
(a -> Maybe b)
-> (forall (e1 :: Effects). Stream a e1 -> Eff (e1 :& es) r)
-> Stream b e2
-> Eff es r
mapMaybe (b -> Maybe b
forall a. a -> Maybe a
Just (b -> Maybe b) -> (a -> b) -> a -> Maybe b
forall b c a. (b -> c) -> (a -> b) -> a -> c
. a -> b
f)

mapMaybe ::
  (e2 :> es) =>
  -- | Yield from the output stream all of the elemnts of the input
  -- stream for which this function returns @Just@
  (a -> Maybe b) ->
  -- | Input stream
  (forall e1. Stream a e1 -> Eff (e1 :& es) r) ->
  Stream b e2 ->
  Eff es r
mapMaybe :: forall (e2 :: Effects) (es :: Effects) a b r.
(e2 :> es) =>
(a -> Maybe b)
-> (forall (e1 :: Effects). Stream a e1 -> Eff (e1 :& es) r)
-> Stream b e2
-> Eff es r
mapMaybe a -> Maybe b
f forall (e1 :: Effects). Stream a e1 -> Eff (e1 :& es) r
s Stream b e2
y = (forall (e1 :: Effects). Stream a e1 -> Eff (e1 :& es) r)
-> (a -> Eff es ()) -> Eff es r
forall a b (es :: Effects) r.
(forall (e1 :: Effects). Coroutine a b e1 -> Eff (e1 :& es) r)
-> (a -> Eff es b) -> Eff es r
forEach Stream a e1 -> Eff (e1 :& es) r
forall (e1 :: Effects). Stream a e1 -> Eff (e1 :& es) r
s ((a -> Eff es ()) -> Eff es r) -> (a -> Eff es ()) -> Eff es r
forall a b. (a -> b) -> a -> b
$ \a
a -> do
  case a -> Maybe b
f a
a of
    Maybe b
Nothing -> () -> Eff es ()
forall a. a -> Eff es a
forall (f :: * -> *) a. Applicative f => a -> f a
pure ()
    Just b
b_ -> Stream b e2 -> b -> Eff es ()
forall (e1 :: Effects) (es :: Effects) a.
(e1 :> es) =>
Stream a e1 -> a -> Eff es ()
yield Stream b e2
y b
b_

-- | Remove 'Nothing' elements from a stream.
catMaybes ::
  (e2 :> es) =>
  -- | Input stream
  (forall e1. Stream (Maybe a) e1 -> Eff (e1 :& es) r) ->
  Stream a e2 ->
  Eff es r
catMaybes :: forall (e2 :: Effects) (es :: Effects) a r.
(e2 :> es) =>
(forall (e1 :: Effects). Stream (Maybe a) e1 -> Eff (e1 :& es) r)
-> Stream a e2 -> Eff es r
catMaybes forall (e1 :: Effects). Stream (Maybe a) e1 -> Eff (e1 :& es) r
s Stream a e2
y = (Maybe a -> Maybe a)
-> (forall (e1 :: Effects).
    Stream (Maybe a) e1 -> Eff (e1 :& es) r)
-> Stream a e2
-> Eff es r
forall (e2 :: Effects) (es :: Effects) a b r.
(e2 :> es) =>
(a -> Maybe b)
-> (forall (e1 :: Effects). Stream a e1 -> Eff (e1 :& es) r)
-> Stream b e2
-> Eff es r
mapMaybe Maybe a -> Maybe a
forall a. a -> a
id Stream (Maybe a) e1 -> Eff (e1 :& es) r
forall (e1 :: Effects). Stream (Maybe a) e1 -> Eff (e1 :& es) r
s Stream a e2
y

type Jump = EarlyReturn ()

-- |
-- @
-- runPureEff $ 'withStateSource' $ \\source -> do
--   n <- 'newState' source 5
--   total <- newState source 0
--
--   'Bluefin.Jump.withJump' $ \\done -> forever $ do
--     n' <- 'Bluefin.State.get' n
--     'Bluefin.State.modify' total (+ n')
--     when (n' == 0) $ 'Bluefin.Jump.jumpTo' done
--     modify n (subtract 1)
--
--   get total
-- 15
-- @
withJump ::
  (forall e. Jump e -> Eff (e :& es) ()) ->
  -- | ͘
  Eff es ()
withJump :: forall (es :: Effects).
(forall (e :: Effects). Jump e -> Eff (e :& es) ()) -> Eff es ()
withJump = (forall (e :: Effects). EarlyReturn () e -> Eff (e :& es) ())
-> Eff es ()
forall r (es :: Effects).
(forall (e :: Effects). EarlyReturn r e -> Eff (e :& es) r)
-> Eff es r
withEarlyReturn

-- |
-- @
-- runPureEff $ 'withStateSource' $ \\source -> do
--   n <- 'newState' source 5
--   total <- newState source 0
--
--   'Bluefin.Jump.withJump' $ \\done -> forever $ do
--     n' <- 'Bluefin.State.get' n
--     'Bluefin.State.modify' total (+ n')
--     when (n' == 0) $ 'Bluefin.Jump.jumpTo' done
--     modify n (subtract 1)
--
--   get total
-- 15
-- @
jumpTo ::
  (e :> es) =>
  Jump e ->
  -- | ͘
  Eff es a
jumpTo :: forall (e :: Effects) (es :: Effects) a.
(e :> es) =>
Jump e -> Eff es a
jumpTo Jump e
tag = Jump e -> () -> Eff es a
forall (e :: Effects) (es :: Effects) ex a.
(e :> es) =>
Exception ex e -> ex -> Eff es a
throw Jump e
tag ()

unwrap :: (e :> es) => Jump e -> Maybe a -> Eff es a
unwrap :: forall (e :: Effects) (es :: Effects) a.
(e :> es) =>
Jump e -> Maybe a -> Eff es a
unwrap Jump e
j = \case
  Maybe a
Nothing -> Jump e -> Eff es a
forall (e :: Effects) (es :: Effects) a.
(e :> es) =>
Jump e -> Eff es a
jumpTo Jump e
j
  Just a
a -> a -> Eff es a
forall a. a -> Eff es a
forall (f :: * -> *) a. Applicative f => a -> f a
pure a
a

-- | Handle that allows you to run 'IO' operations
data IOE (e :: Effects) = MkIOE

-- | Run an 'IO' operation in 'Eff'
--
-- @
-- >>> runEff $ \\io -> do
--       effIO io (putStrLn "Hello world!")
-- Hello, world!
-- @
effIO ::
  (e :> es) =>
  IOE e ->
  IO a ->
  -- | ͘
  Eff es a
effIO :: forall (e :: Effects) (es :: Effects) a.
(e :> es) =>
IOE e -> IO a -> Eff es a
effIO IOE e
MkIOE = IO a -> Eff es a
forall (es :: Effects) a. IO a -> Eff es a
UnsafeMkEff

-- | Run an 'Eff' whose only unhandled effect is 'IO'.
--
-- @
-- >>> runEff $ \\io -> do
--       effIO io (putStrLn "Hello world!")
-- Hello, world!
-- @
runEff ::
  (forall e es. IOE e -> Eff (e :& es) a) ->
  -- | ͘
  IO a
runEff :: forall a.
(forall (e :: Effects) (es :: Effects). IOE e -> Eff (e :& es) a)
-> IO a
runEff forall (e :: Effects) (es :: Effects). IOE e -> Eff (e :& es) a
eff = Eff (Any :& Any) a -> IO a
forall (es :: Effects) a. Eff es a -> IO a
unsafeUnEff (IOE Any -> Eff (Any :& Any) a
forall (e :: Effects) (es :: Effects). IOE e -> Eff (e :& es) a
eff IOE Any
forall (e :: Effects). IOE e
MkIOE)

unsafeProvideIO ::
  (forall e. IOE e -> Eff (e :& es) a) ->
  -- | ͘
  Eff es a
unsafeProvideIO :: forall (es :: Effects) a.
(forall (e :: Effects). IOE e -> Eff (e :& es) a) -> Eff es a
unsafeProvideIO forall (e :: Effects). IOE e -> Eff (e :& es) a
eff = Eff (Any :& es) a -> Eff es a
forall (e :: Effects) (es :: Effects) a.
Eff (e :& es) a -> Eff es a
unsafeRemoveEff (IOE Any -> Eff (Any :& es) a
forall (e :: Effects). IOE e -> Eff (e :& es) a
eff IOE Any
forall (e :: Effects). IOE e
MkIOE)

connect ::
  (forall e1. Coroutine a b e1 -> Eff (e1 :& es) r1) ->
  (forall e2. a -> Coroutine b a e2 -> Eff (e2 :& es) r2) ->
  forall e1 e2.
  (e1 :> es, e2 :> es) =>
  Eff
    es
    ( Either
        (r1, a -> Coroutine b a e2 -> Eff es r2)
        (r2, b -> Coroutine a b e1 -> Eff es r1)
    )
connect :: forall a b (es :: Effects) r1 r2.
(forall (e1 :: Effects). Coroutine a b e1 -> Eff (e1 :& es) r1)
-> (forall (e2 :: Effects).
    a -> Coroutine b a e2 -> Eff (e2 :& es) r2)
-> forall (e1 :: Effects) (e2 :: Effects).
   (e1 :> es, e2 :> es) =>
   Eff
     es
     (Either
        (r1, a -> Coroutine b a e2 -> Eff es r2)
        (r2, b -> Coroutine a b e1 -> Eff es r1))
connect forall (e1 :: Effects). Coroutine a b e1 -> Eff (e1 :& es) r1
_ forall (e2 :: Effects). a -> Coroutine b a e2 -> Eff (e2 :& es) r2
_ = String
-> Eff
     es
     (Either
        (r1, a -> Coroutine b a e2 -> Eff es r2)
        (r2, b -> Coroutine a b e1 -> Eff es r1))
forall a. HasCallStack => String -> a
error String
"connect unimplemented, sorry"

head' ::
  forall a b r es.
  (forall e. Coroutine a b e -> Eff (e :& es) r) ->
  forall e.
  (e :> es) =>
  Eff
    es
    ( Either
        r
        (a, b -> Coroutine a b e -> Eff es r)
    )
head' :: forall a b r (es :: Effects).
(forall (e :: Effects). Coroutine a b e -> Eff (e :& es) r)
-> forall (e :: Effects).
   (e :> es) =>
   Eff es (Either r (a, b -> Coroutine a b e -> Eff es r))
head' forall (e :: Effects). Coroutine a b e -> Eff (e :& es) r
c = do
  Either
  (r, a -> Coroutine b a es -> Eff es a)
  (a, b -> Coroutine a b e -> Eff es r)
r <- (forall (e :: Effects). Coroutine a b e -> Eff (e :& es) r)
-> (forall (e2 :: Effects).
    a -> Coroutine b a e2 -> Eff (e2 :& es) a)
-> forall (e1 :: Effects) (e2 :: Effects).
   (e1 :> es, e2 :> es) =>
   Eff
     es
     (Either
        (r, a -> Coroutine b a e2 -> Eff es a)
        (a, b -> Coroutine a b e1 -> Eff es r))
forall a b (es :: Effects) r1 r2.
(forall (e1 :: Effects). Coroutine a b e1 -> Eff (e1 :& es) r1)
-> (forall (e2 :: Effects).
    a -> Coroutine b a e2 -> Eff (e2 :& es) r2)
-> forall (e1 :: Effects) (e2 :: Effects).
   (e1 :> es, e2 :> es) =>
   Eff
     es
     (Either
        (r1, a -> Coroutine b a e2 -> Eff es r2)
        (r2, b -> Coroutine a b e1 -> Eff es r1))
connect Coroutine a b e1 -> Eff (e1 :& es) r
forall (e :: Effects). Coroutine a b e -> Eff (e :& es) r
c (\a
a Coroutine b a e2
_ -> a -> Eff (e2 :& es) a
forall a. a -> Eff (e2 :& es) a
forall (f :: * -> *) a. Applicative f => a -> f a
pure a
a) @_ @es
  Either r (a, b -> Coroutine a b e -> Eff es r)
-> Eff es (Either r (a, b -> Coroutine a b e -> Eff es r))
forall a. a -> Eff es a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Either r (a, b -> Coroutine a b e -> Eff es r)
 -> Eff es (Either r (a, b -> Coroutine a b e -> Eff es r)))
-> Either r (a, b -> Coroutine a b e -> Eff es r)
-> Eff es (Either r (a, b -> Coroutine a b e -> Eff es r))
forall a b. (a -> b) -> a -> b
$ case Either
  (r, a -> Coroutine b a es -> Eff es a)
  (a, b -> Coroutine a b e -> Eff es r)
r of
    Right (a, b -> Coroutine a b e -> Eff es r)
r' -> (a, b -> Coroutine a b e -> Eff es r)
-> Either r (a, b -> Coroutine a b e -> Eff es r)
forall a b. b -> Either a b
Right (a, b -> Coroutine a b e -> Eff es r)
r'
    Left (r
l, a -> Coroutine b a es -> Eff es a
_) -> r -> Either r (a, b -> Coroutine a b e -> Eff es r)
forall a b. a -> Either a b
Left r
l

newtype Writer w e = Writer (Stream w e)

-- |
-- @
-- >>> 'Data.Monoid.getAny' $ snd $ runPureEff $ runWriter $ \\w -> do
--       -- Non-empty list (the tell event does happen)
--       for_ [1 .. 10] $ \\_ -> tell w ('Data.Monoid.Any' True)
-- True
-- @
runWriter ::
  (Monoid w) =>
  -- | ͘
  (forall e. Writer w e -> Eff (e :& es) r) ->
  Eff es (r, w)
runWriter :: forall w (es :: Effects) r.
Monoid w =>
(forall (e :: Effects). Writer w e -> Eff (e :& es) r)
-> Eff es (r, w)
runWriter forall (e :: Effects). Writer w e -> Eff (e :& es) r
f = w
-> (forall {e :: Effects}. State w e -> Eff (e :& es) r)
-> Eff es (r, w)
forall s (es :: Effects) a.
s
-> (forall (e :: Effects). State s e -> Eff (e :& es) a)
-> Eff es (a, s)
runState w
forall a. Monoid a => a
mempty ((forall {e :: Effects}. State w e -> Eff (e :& es) r)
 -> Eff es (r, w))
-> (forall {e :: Effects}. State w e -> Eff (e :& es) r)
-> Eff es (r, w)
forall a b. (a -> b) -> a -> b
$ \State w e
st -> do
  (forall (e1 :: Effects).
 Coroutine w () e1 -> Eff (e1 :& (e :& es)) r)
-> (w -> Eff (e :& es) ()) -> Eff (e :& es) r
forall a b (es :: Effects) r.
(forall (e1 :: Effects). Coroutine a b e1 -> Eff (e1 :& es) r)
-> (a -> Eff es b) -> Eff es r
forEach (Eff (e1 :& es) r -> Eff (e1 :& (e :& es)) r
forall (c1 :: Effects) (b :: Effects) r (c2 :: Effects).
Eff (c1 :& b) r -> Eff (c1 :& (c2 :& b)) r
insertSecond (Eff (e1 :& es) r -> Eff (e1 :& (e :& es)) r)
-> (Coroutine w () e1 -> Eff (e1 :& es) r)
-> Coroutine w () e1
-> Eff (e1 :& (e :& es)) r
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Writer w e1 -> Eff (e1 :& es) r
forall (e :: Effects). Writer w e -> Eff (e :& es) r
f (Writer w e1 -> Eff (e1 :& es) r)
-> (Coroutine w () e1 -> Writer w e1)
-> Coroutine w () e1
-> Eff (e1 :& es) r
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Coroutine w () e1 -> Writer w e1
forall w (e :: Effects). Stream w e -> Writer w e
Writer) ((w -> Eff (e :& es) ()) -> Eff (e :& es) r)
-> (w -> Eff (e :& es) ()) -> Eff (e :& es) r
forall a b. (a -> b) -> a -> b
$ \w
ww -> do
    State w e -> (w -> w) -> Eff (e :& es) ()
forall (e :: Effects) (es :: Effects) s.
(e :> es) =>
State s e -> (s -> s) -> Eff es ()
modify State w e
st (w -> w -> w
forall a. Semigroup a => a -> a -> a
<> w
ww)

-- |
-- @
-- >>> 'Data.Monoid.getAny' $ runPureEff $ execWriter $ \\w -> do
--       -- Non-empty list (the tell event does happen)
--       for_ [1 .. 10] $ \\_ -> tell w ('Data.Monoid.Any' True)
-- True
-- @
--
-- @
-- >>> 'Data.Monoid.getAny' $ runPureEff $ execWriter $ \\w -> do
--       -- Empty list (the tell event does not happen)
--       for_ [] $ \\_ -> tell w ('Data.Monoid.Any' True)
-- False
-- @
execWriter ::
  (Monoid w) =>
  -- | ͘
  (forall e. Writer w e -> Eff (e :& es) r) ->
  Eff es w
execWriter :: forall w (es :: Effects) r.
Monoid w =>
(forall (e :: Effects). Writer w e -> Eff (e :& es) r) -> Eff es w
execWriter forall (e :: Effects). Writer w e -> Eff (e :& es) r
f = ((r, w) -> w) -> Eff es (r, w) -> Eff es w
forall a b. (a -> b) -> Eff es a -> Eff es b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (r, w) -> w
forall a b. (a, b) -> b
snd ((forall (e :: Effects). Writer w e -> Eff (e :& es) r)
-> Eff es (r, w)
forall w (es :: Effects) r.
Monoid w =>
(forall (e :: Effects). Writer w e -> Eff (e :& es) r)
-> Eff es (r, w)
runWriter Writer w e -> Eff (e :& es) r
forall (e :: Effects). Writer w e -> Eff (e :& es) r
f)

-- |
-- @
-- >>> 'Data.Monoid.getAny' $ runPureEff $ execWriter $ \\w -> do
--       -- Non-empty list (the tell event does happen)
--       for_ [1 .. 10] $ \\_ -> tell w ('Data.Monoid.Any' True)
-- True
-- @
tell ::
  (e :> es) =>
  Writer w e ->
  -- | ͘
  w ->
  Eff es ()
tell :: forall (e :: Effects) (es :: Effects) w.
(e :> es) =>
Writer w e -> w -> Eff es ()
tell (Writer Stream w e
y) = Stream w e -> w -> Eff es ()
forall (e1 :: Effects) (es :: Effects) a.
(e1 :> es) =>
Stream a e1 -> a -> Eff es ()
yield Stream w e
y

newtype Reader r (e :: Effects) = MkReader r

instance Handle (Reader r) where
  mapHandle :: forall (e :: Effects) (es :: Effects).
(e :> es) =>
Reader r e -> Reader r es
mapHandle (MkReader r
r) = r -> Reader r es
forall r (e :: Effects). r -> Reader r e
MkReader r
r

runReader ::
  -- | ͘
  r ->
  (forall e. Reader r e -> Eff (e :& es) a) ->
  Eff es a
runReader :: forall r (es :: Effects) a.
r
-> (forall (e :: Effects). Reader r e -> Eff (e :& es) a)
-> Eff es a
runReader r
r forall (e :: Effects). Reader r e -> Eff (e :& es) a
f = Eff (Any :& es) a -> Eff es a
forall (e :: Effects) (es :: Effects) a.
Eff (e :& es) a -> Eff es a
unsafeRemoveEff (Reader r Any -> Eff (Any :& es) a
forall (e :: Effects). Reader r e -> Eff (e :& es) a
f (r -> Reader r Any
forall r (e :: Effects). r -> Reader r e
MkReader r
r))

ask ::
  (e :> es) =>
  -- | ͘
  Reader r e ->
  Eff es r
ask :: forall (e :: Effects) (es :: Effects) r.
(e :> es) =>
Reader r e -> Eff es r
ask (MkReader r
r) = r -> Eff es r
forall a. a -> Eff es a
forall (f :: * -> *) a. Applicative f => a -> f a
pure r
r