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

module Bluefin.Internal where

import Control.Exception (throwIO, tryJust)
import qualified Control.Exception
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)))

-- 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
                      )
                )
            )
      )

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 (ex :: Effects) (es :: Effects) e a.
(ex :> es) =>
Exception e ex -> e -> 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 (# #))))

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)

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

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

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

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

-- | A handle to a stream that yields values of type @a@.  It is
-- implemented as a handle to a coroutine that expects values of type
-- @()@ and then yields values of type @a@.
type Stream 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 (st :: Effects). IORef s -> State s st
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 e (ex :: Effects). (forall a. e -> IO a) -> Exception e ex
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 (s :: Effects). (a -> Eff s b) -> Coroutine a b s
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 ::
  (ex :> es) =>
  Exception e ex ->
  -- | Value to throw
  e ->
  Eff es a
throw :: forall (ex :: Effects) (es :: Effects) e a.
(ex :> es) =>
Exception e ex -> e -> Eff es a
throw (UnsafeMkException forall a. e -> IO a
throw_) e
e = IO a -> Eff es a
forall (es :: Effects) a. IO a -> Eff es a
UnsafeMkEff (e -> IO a
forall a. e -> IO a
throw_ e
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 e (es :: Effects) a.
  (forall ex. Exception e ex -> Eff (ex :& es) a) ->
  -- | @Left@ if the exception was thrown, @Right@ otherwise
  Eff es (Either e a)
try :: forall e (es :: Effects) a.
(forall (ex :: Effects). Exception e ex -> Eff (ex :& es) a)
-> Eff es (Either e a)
try forall (ex :: Effects). Exception e ex -> Eff (ex :& es) a
f =
  IO (Either e a) -> Eff es (Either e a)
forall (es :: Effects) a. IO a -> Eff es a
UnsafeMkEff (IO (Either e a) -> Eff es (Either e a))
-> IO (Either e a) -> Eff es (Either e a)
forall a b. (a -> b) -> a -> b
$ ((forall a. e -> IO a) -> IO a) -> IO (Either e a)
forall e r. ((forall a. e -> IO a) -> IO r) -> IO (Either e r)
withScopedException_ (\forall a. e -> IO a
throw_ -> Eff (Any :& es) a -> IO a
forall (es :: Effects) a. Eff es a -> IO a
unsafeUnEff (Exception e Any -> Eff (Any :& es) a
forall (ex :: Effects). Exception e ex -> Eff (ex :& es) a
f ((forall a. e -> IO a) -> Exception e Any
forall e (ex :: Effects). (forall a. e -> IO a) -> Exception e ex
UnsafeMkException e -> IO a
forall a. e -> 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 e (es :: Effects) a.
  -- | If the exception is thrown, apply this handler
  (e -> Eff es a) ->
  (forall ex. Exception e ex -> Eff (ex :& es) a) ->
  Eff es a
handle :: forall e (es :: Effects) a.
(e -> Eff es a)
-> (forall (ex :: Effects). Exception e ex -> Eff (ex :& es) a)
-> Eff es a
handle e -> Eff es a
h forall (ex :: Effects). Exception e ex -> Eff (ex :& es) a
f =
  (forall (ex :: Effects). Exception e ex -> Eff (ex :& es) a)
-> Eff es (Either e a)
forall e (es :: Effects) a.
(forall (ex :: Effects). Exception e ex -> Eff (ex :& es) a)
-> Eff es (Either e a)
try Exception e ex -> Eff (ex :& es) a
forall (ex :: Effects). Exception e ex -> Eff (ex :& es) a
f Eff es (Either e a) -> (Either e 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 e
e -> e -> Eff es a
h e
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 e (es :: Effects) a.
  (forall ex. Exception e ex -> Eff (ex :& es) a) ->
  -- | If the exception is thrown, apply this handler
  (e -> Eff es a) ->
  Eff es a
catch :: forall e (es :: Effects) a.
(forall (ex :: Effects). Exception e ex -> Eff (ex :& es) a)
-> (e -> Eff es a) -> Eff es a
catch forall (ex :: Effects). Exception e ex -> Eff (ex :& es) a
f e -> Eff es a
h = (e -> Eff es a)
-> (forall (ex :: Effects). Exception e ex -> Eff (ex :& es) a)
-> Eff es a
forall e (es :: Effects) a.
(e -> Eff es a)
-> (forall (ex :: Effects). Exception e ex -> Eff (ex :& es) a)
-> Eff es a
handle e -> Eff es a
h Exception e ex -> Eff (ex :& es) a
forall (ex :: Effects). Exception e ex -> Eff (ex :& 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 ::
  Eff es a ->
  (a -> Eff es ()) ->
  (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 ::
  (st :> es) =>
  State s st ->
  -- | The current value of the state
  Eff es s
get :: forall (st :: Effects) (es :: Effects) s.
(st :> es) =>
State s st -> 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 ::
  (st :> es) =>
  State s st ->
  -- | The new value of the state.  The new value is forced before
  -- writing it to the state.
  s ->
  Eff es ()
put :: forall (st :: Effects) (es :: Effects) s.
(st :> es) =>
State s st -> 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 ::
  (st :> es) =>
  State s st ->
  -- | 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 (st :: Effects) (es :: Effects) s.
(st :> es) =>
State s st -> (s -> s) -> Eff es ()
modify State s st
state s -> s
f = do
  s
s <- State s st -> Eff es s
forall (st :: Effects) (es :: Effects) s.
(st :> es) =>
State s st -> Eff es s
get State s st
state
  State s st -> s -> Eff es ()
forall (st :: Effects) (es :: Effects) s.
(st :> es) =>
State s st -> s -> Eff es ()
put State s st
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 (st :: Effects). StateSource st
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 (st :: Effects). IORef s -> State s st
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 st. State s st -> Eff (st :& es) a) ->
  -- | Result and final state
  Eff es (a, s)
runState :: forall s (es :: Effects) a.
s
-> (forall (st :: Effects). State s st -> Eff (st :& es) a)
-> Eff es (a, s)
runState s
s forall (st :: Effects). State s st -> Eff (st :& 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 (st :: Effects). State s st -> Eff (st :& es) a
f State s e
state
    s
s' <- State s e -> Eff (e :& es) s
forall (st :: Effects) (es :: Effects) s.
(st :> es) =>
State s st -> 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 (s :: Effects). (a -> Eff s b) -> Coroutine a b s
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 {st :: Effects}. State Int st -> Eff (st :& es) r)
-> Eff es r
forall s (es :: Effects) a.
s
-> (forall (st :: Effects). State s st -> Eff (st :& es) a)
-> Eff es a
evalState Int
n ((forall {st :: Effects}. State Int st -> Eff (st :& es) r)
 -> Eff es r)
-> (forall {st :: Effects}. State Int st -> Eff (st :& es) r)
-> Eff es r
forall a b. (a -> b) -> a -> b
$ \State Int st
i -> (forall (e1 :: Effects).
 Coroutine a () e1 -> Eff (e1 :& (st :& es)) r)
-> (a -> Eff (st :& es) ()) -> Eff (st :& 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 :& (st :& 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 :& (st :& es)) r)
-> (Coroutine a () e1 -> Eff (e1 :& es) r)
-> Coroutine a () e1
-> Eff (e1 :& (st :& 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 (st :& es) ()) -> Eff (st :& es) r)
-> (a -> Eff (st :& es) ()) -> Eff (st :& es) r
forall a b. (a -> b) -> a -> b
$ \a
s -> do
    Int
ii <- State Int st -> Eff (st :& es) Int
forall (st :: Effects) (es :: Effects) s.
(st :> es) =>
State s st -> Eff es s
get State Int st
i
    Stream (Int, a) e2 -> (Int, a) -> Eff (st :& 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 st -> Int -> Eff (st :& es) ()
forall (st :: Effects) (es :: Effects) s.
(st :> es) =>
State s st -> s -> Eff es ()
put State Int st
i (Int
ii Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
1)

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 er. EarlyReturn r er -> Eff (er :& es) r) ->
  -- | ͘
  Eff es r
withEarlyReturn :: forall r (es :: Effects).
(forall (er :: Effects). EarlyReturn r er -> Eff (er :& es) r)
-> Eff es r
withEarlyReturn = (r -> Eff es r)
-> (forall (er :: Effects). EarlyReturn r er -> Eff (er :& es) r)
-> Eff es r
forall e (es :: Effects) a.
(e -> Eff es a)
-> (forall (ex :: Effects). Exception e ex -> Eff (ex :& 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 ::
  (er :> es) =>
  EarlyReturn r er ->
  -- | Return early to the handler, with this value.
  r ->
  Eff es a
returnEarly :: forall (ex :: Effects) (es :: Effects) e a.
(ex :> es) =>
Exception e ex -> e -> Eff es a
returnEarly = Exception r er -> r -> Eff es a
forall (ex :: Effects) (es :: Effects) e a.
(ex :> es) =>
Exception e ex -> e -> Eff es a
throw

-- |
-- @
-- >>> runPureEff $ evalState 10 $ \\st -> do
--       n <- get st
--       pure (2 * n)
-- 20
-- @
evalState ::
  -- | Initial state
  s ->
  -- | Stateful computation
  (forall st. State s st -> Eff (st :& es) a) ->
  -- | Result
  Eff es a
evalState :: forall s (es :: Effects) a.
s
-> (forall (st :: Effects). State s st -> Eff (st :& es) a)
-> Eff es a
evalState s
s forall (st :: Effects). State s st -> Eff (st :& 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 (st :: Effects). State s st -> Eff (st :& es) a)
-> Eff es (a, s)
forall s (es :: Effects) a.
s
-> (forall (st :: Effects). State s st -> Eff (st :& es) a)
-> Eff es (a, s)
runState s
s State s st -> Eff (st :& es) a
forall (st :: Effects). State s st -> Eff (st :& 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 (st :: Effects). State s st -> Eff (st :& es) a)
-> Eff es (a, s)
runState s
s State s st -> Eff (st :& 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 (st :: Effects) (es :: Effects) s.
(st :> es) =>
State s st -> 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 (st :: Effects) (es :: Effects) s.
(st :> es) =>
State s st -> 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 {st :: Effects}.
    State [a] st -> Eff (st :& es) ([a], r))
-> Eff es ([a], r)
forall s (es :: Effects) a.
s
-> (forall (st :: Effects). State s st -> Eff (st :& es) a)
-> Eff es a
evalState [] ((forall {st :: Effects}. State [a] st -> Eff (st :& es) ([a], r))
 -> Eff es ([a], r))
-> (forall {st :: Effects}.
    State [a] st -> Eff (st :& es) ([a], r))
-> Eff es ([a], r)
forall a b. (a -> b) -> a -> b
$ \(State [a] st
s :: State lo st) -> do
    r
r <- (forall (e1 :: Effects).
 Coroutine a () e1 -> Eff (e1 :& (st :& es)) r)
-> (a -> Eff (st :& es) ()) -> Eff (st :& 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 :& (st :& 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 :& (st :& es)) r)
-> (Coroutine a () e1 -> Eff (e1 :& es) r)
-> Coroutine a () e1
-> Eff (e1 :& (st :& 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 (st :& es) ()) -> Eff (st :& es) r)
-> (a -> Eff (st :& es) ()) -> Eff (st :& es) r
forall a b. (a -> b) -> a -> b
$ \a
i ->
      State [a] st -> ([a] -> [a]) -> Eff (st :& es) ()
forall (st :: Effects) (es :: Effects) s.
(st :> es) =>
State s st -> (s -> s) -> Eff es ()
modify State [a] st
s (a
i :)
    [a]
as <- State [a] st -> Eff (st :& es) [a]
forall (st :: Effects) (es :: Effects) s.
(st :> es) =>
State s st -> Eff es s
get State [a] st
s
    ([a], r) -> Eff (st :& es) ([a], r)
forall a. a -> Eff (st :& 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 j. Jump j -> Eff (j :& es) ()) ->
  -- | ͘
  Eff es ()
withJump :: forall (es :: Effects).
(forall (j :: Effects). Jump j -> Eff (j :& es) ()) -> Eff es ()
withJump = (forall (er :: Effects). EarlyReturn () er -> Eff (er :& es) ())
-> Eff es ()
forall r (es :: Effects).
(forall (er :: Effects). EarlyReturn r er -> Eff (er :& 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 ::
  (j :> es) =>
  Jump j ->
  -- | ͘
  Eff es a
jumpTo :: forall (j :: Effects) (es :: Effects) a.
(j :> es) =>
Jump j -> Eff es a
jumpTo Jump j
tag = Jump j -> () -> Eff es a
forall (ex :: Effects) (es :: Effects) e a.
(ex :> es) =>
Exception e ex -> e -> Eff es a
throw Jump j
tag ()

unwrap :: (j :> es) => Jump j -> Maybe a -> Eff es a
unwrap :: forall (j :: Effects) (es :: Effects) a.
(j :> es) =>
Jump j -> Maybe a -> Eff es a
unwrap Jump j
j = \case
  Maybe a
Nothing -> Jump j -> Eff es a
forall (j :: Effects) (es :: Effects) a.
(j :> es) =>
Jump j -> Eff es a
jumpTo Jump j
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)

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 {st :: Effects}. State w st -> Eff (st :& es) r)
-> Eff es (r, w)
forall s (es :: Effects) a.
s
-> (forall (st :: Effects). State s st -> Eff (st :& es) a)
-> Eff es (a, s)
runState w
forall a. Monoid a => a
mempty ((forall {st :: Effects}. State w st -> Eff (st :& es) r)
 -> Eff es (r, w))
-> (forall {st :: Effects}. State w st -> Eff (st :& es) r)
-> Eff es (r, w)
forall a b. (a -> b) -> a -> b
$ \State w st
st -> do
  (forall (e1 :: Effects).
 Coroutine w () e1 -> Eff (e1 :& (st :& es)) r)
-> (w -> Eff (st :& es) ()) -> Eff (st :& 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 :& (st :& 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 :& (st :& es)) r)
-> (Coroutine w () e1 -> Eff (e1 :& es) r)
-> Coroutine w () e1
-> Eff (e1 :& (st :& 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 (st :& es) ()) -> Eff (st :& es) r)
-> (w -> Eff (st :& es) ()) -> Eff (st :& es) r
forall a b. (a -> b) -> a -> b
$ \w
ww -> do
    State w st -> (w -> w) -> Eff (st :& es) ()
forall (st :: Effects) (es :: Effects) s.
(st :> es) =>
State s st -> (s -> s) -> Eff es ()
modify State w st
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