Safe Haskell | Safe-Inferred |
---|---|
Language | Haskell2010 |
Bluefin.Internal
Synopsis
- data Effects = Union Effects Effects
- type (:&) = Union
- newtype Eff (es :: Effects) a = UnsafeMkEff {
- unsafeUnEff :: IO a
- newtype EffReader r es a = MkEffReader {
- unEffReader :: r -> Eff es a
- effReader :: (r -> Eff es a) -> EffReader r es a
- runEffReader :: r -> EffReader r es a -> Eff es a
- withEffToIO :: e2 :> es => ((forall r. (forall e1. IOE e1 -> Eff (e1 :& es) r) -> IO r) -> IO a) -> IOE e2 -> Eff es a
- withEffToIO' :: e2 :> es => IOE e2 -> ((forall r. (forall e1. IOE e1 -> Eff (e1 :& es) r) -> IO r) -> IO a) -> Eff es a
- withEffToIO_ :: e :> es => IOE e -> ((forall r. Eff es r -> IO r) -> IO a) -> Eff es a
- withEffToIO_' :: e2 :> es => IOE e2 -> ((forall r. (forall e1. IOE e1 -> Eff (e1 :& es) r) -> IO r) -> IO a) -> Eff es a
- race :: e2 :> es => (forall e. IOE e -> Eff (e :& es) a) -> (forall e. IOE e -> Eff (e :& es) a) -> IOE e2 -> Eff es 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
- receiveStream :: (forall e. Consume a e -> Eff (e :& es) r) -> (forall e. Stream a e -> Eff (e :& es) r) -> Eff es r
- consumeStream :: (forall e. Consume a e -> Eff (e :& es) r) -> (forall e. Stream a e -> Eff (e :& es) r) -> Eff es r
- 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
- hoistReader :: (forall b. m b -> n b) -> ReaderT r m a -> ReaderT r n a
- withMonadIO :: e :> es => IOE e -> (forall m. MonadIO m => m r) -> Eff es r
- withMonadFail :: e :> es => Exception String e -> (forall m. MonadFail m => m r) -> Eff es r
- unsafeRemoveEff :: Eff (e :& es) a -> Eff es a
- runPureEff :: (forall es. Eff es a) -> a
- weakenEff :: (t `In` t') -> Eff t r -> Eff t' r
- insertFirst :: Eff b r -> Eff (c1 :& b) r
- insertSecond :: Eff (c1 :& b) r -> Eff (c1 :& (c2 :& b)) r
- insertManySecond :: b :> c => Eff (c1 :& b) r -> Eff (c1 :& c) r
- assoc1Eff :: Eff ((a :& b) :& c) r -> Eff (a :& (b :& c)) r
- pushFirst :: Eff a r -> Eff (a :& b) r
- mergeEff :: Eff (a :& a) r -> Eff a r
- inContext :: e2 :> e1 => Eff (e1 :& e2) r -> Eff e1 r
- makeOp :: Eff (e :& e) r -> Eff e r
- useImpl :: e :> es => Eff e r -> Eff es r
- useImplUnder :: e :> es => Eff (e1 :& e) r -> Eff (e1 :& es) r
- useImplIn :: e :> es => (t -> Eff (es :& e) r) -> t -> Eff es r
- useImplWithin :: e :> es => (t -> Eff (e1 :& e) r) -> t -> Eff (e1 :& es) r
- data StateSource (e :: Effects) = StateSource
- newtype Exception exn (e :: Effects) = UnsafeMkException (forall a. exn -> IO a)
- newtype State s (e :: Effects) = UnsafeMkState (IORef s)
- newtype Coroutine a b (e :: Effects) = MkCoroutine (a -> Eff e b)
- type Stream a = Coroutine a ()
- type Consume a = Coroutine () a
- class Handle (h :: Effects -> Type) where
- newtype In (a :: Effects) (b :: Effects) = In# (# #)
- merge :: (# #) -> (a :& a) `In` a
- eq :: (# #) -> a `In` a
- fstI :: (# #) -> a `In` (a :& b)
- sndI :: (# #) -> a `In` (b :& a)
- cmp :: (a `In` b) -> (b `In` c) -> a `In` c
- bimap :: (a `In` b) -> (c `In` d) -> (a :& c) `In` (b :& d)
- assoc1 :: (# #) -> ((a :& b) :& c) `In` (a :& (b :& c))
- drop :: (a `In` b) -> a `In` (c :& b)
- here :: (a `In` b) -> a `In` (b :& c)
- w :: ((a :& b) `In` c) -> a `In` c
- w2 :: ((b :& a) `In` c) -> a `In` c
- b2 :: (a `In` b) -> (a :& c) `In` (b :& c)
- b :: (a `In` b) -> (c :& a) `In` (c :& b)
- subsume1 :: (e2 `In` e1) -> (e1 :& e2) `In` e1
- subsume2 :: (e1 `In` e2) -> (e1 :& e2) `In` e2
- class (es1 :: Effects) :> (es2 :: Effects)
- throw :: e :> es => Exception ex e -> ex -> Eff es a
- has :: forall a b. a :> b => a `In` b
- data Dict c where
- have :: forall a b. (a `In` b) -> Dict (a :> b)
- try :: forall exn (es :: Effects) a. (forall e. Exception exn e -> Eff (e :& es) a) -> Eff es (Either exn a)
- handle :: forall exn (es :: Effects) a. (exn -> Eff es a) -> (forall e. Exception exn e -> Eff (e :& es) a) -> Eff es a
- catch :: forall exn (es :: Effects) a. (forall e. Exception exn e -> Eff (e :& es) a) -> (exn -> Eff es a) -> Eff es a
- rethrowIO :: forall ex es e1 e2 r. (e1 :> es, e2 :> es, Exception ex) => IOE e1 -> Exception ex e2 -> Eff es r -> Eff es r
- bracket :: Eff es a -> (a -> Eff es ()) -> (a -> Eff es b) -> Eff es b
- get :: e :> es => State s e -> Eff es s
- put :: e :> es => State s e -> s -> Eff es ()
- modify :: e :> es => State s e -> (s -> s) -> Eff es ()
- data MyException where
- MyException :: e -> Unique -> MyException
- withScopedException_ :: ((forall a. e -> IO a) -> IO r) -> IO (Either e r)
- withStateSource :: (forall e. StateSource e -> Eff (e :& es) a) -> Eff es a
- newState :: StateSource e -> s -> Eff es (State s e)
- runState :: s -> (forall e. State s e -> Eff (e :& es) a) -> Eff es (a, s)
- yieldCoroutine :: e1 :> es => Coroutine a b e1 -> a -> Eff es b
- yield :: e1 :> es => Stream a e1 -> a -> Eff es ()
- handleCoroutine :: (a -> Eff es b) -> (z -> Eff es r) -> (forall e1. Coroutine a b e1 -> Eff (e1 :& es) z) -> Eff es r
- forEach :: (forall e1. Coroutine a b e1 -> Eff (e1 :& es) r) -> (a -> Eff es b) -> Eff es r
- ignoreStream :: (forall e1. Stream a e1 -> Eff (e1 :& es) r) -> Eff es r
- inFoldable :: (Foldable t, e1 :> es) => t a -> Stream a e1 -> Eff es ()
- enumerate :: e2 :> es => (forall e1. Stream a e1 -> Eff (e1 :& es) r) -> Stream (Int, a) e2 -> Eff es r
- enumerateFrom :: e2 :> es => Int -> (forall e1. Stream a e1 -> Eff (e1 :& es) r) -> Stream (Int, a) e2 -> Eff es r
- consumeEach :: (forall e. Consume b e -> Eff (e :& es) r) -> Eff es b -> Eff es r
- await :: e :> es => Consume a e -> Eff es a
- type EarlyReturn = Exception
- withEarlyReturn :: (forall e. EarlyReturn r e -> Eff (e :& es) r) -> Eff es r
- returnEarly :: e :> es => EarlyReturn r e -> r -> Eff es a
- evalState :: s -> (forall e. State s e -> Eff (e :& es) a) -> Eff es a
- withState :: s -> (forall e. State s e -> Eff (e :& es) (s -> a)) -> Eff es a
- data Compound e1 e2 ss where
- compound :: h1 e1 -> h2 e2 -> Compound h1 h2 (e1 :& e2)
- inComp :: forall a b c r. a :> b => b :> c => (a :> c => r) -> r
- 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
- 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
- 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
- putC :: forall ss es e. ss :> es => Compound e (State Int) ss -> Int -> Eff es ()
- getC :: forall ss es e. ss :> es => Compound e (State Int) ss -> Eff es Int
- runCompound :: e1 s1 -> e2 s2 -> (forall es'. Compound e1 e2 es' -> Eff (es' :& es) r) -> Eff (s1 :& (s2 :& es)) r
- yieldToList :: (forall e1. Stream a e1 -> Eff (e1 :& es) r) -> Eff es ([a], r)
- withYieldToList :: (forall e. Stream a e -> Eff (e :& es) ([a] -> r)) -> Eff es r
- yieldToReverseList :: (forall e. Stream a e -> Eff (e :& es) r) -> Eff es ([a], r)
- mapStream :: e2 :> es => (a -> b) -> (forall e1. Stream a e1 -> Eff (e1 :& es) r) -> Stream b e2 -> Eff es r
- mapMaybe :: e2 :> es => (a -> Maybe b) -> (forall e1. Stream a e1 -> Eff (e1 :& es) r) -> Stream b e2 -> Eff es r
- catMaybes :: e2 :> es => (forall e1. Stream (Maybe a) e1 -> Eff (e1 :& es) r) -> Stream a e2 -> Eff es r
- type Jump = EarlyReturn ()
- withJump :: (forall e. Jump e -> Eff (e :& es) ()) -> Eff es ()
- jumpTo :: e :> es => Jump e -> Eff es a
- unwrap :: e :> es => Jump e -> Maybe a -> Eff es a
- data IOE (e :: Effects) = MkIOE
- effIO :: e :> es => IOE e -> IO a -> Eff es a
- runEff :: (forall e es. IOE e -> Eff (e :& es) a) -> IO a
- runEff_ :: (forall e. IOE e -> Eff e a) -> IO a
- unsafeProvideIO :: (forall e. IOE e -> Eff (e :& es) a) -> Eff es a
- 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))
- 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))
- newtype Writer w e = Writer (Stream w e)
- runWriter :: Monoid w => (forall e. Writer w e -> Eff (e :& es) r) -> Eff es (r, w)
- execWriter :: Monoid w => (forall e. Writer w e -> Eff (e :& es) r) -> Eff es w
- tell :: e :> es => Writer w e -> w -> Eff es ()
- newtype Reader r e = MkReader (State r e)
- runReader :: r -> (forall e. Reader r e -> Eff (e :& es) a) -> Eff es a
- ask :: e :> es => Reader r e -> Eff es r
- asks :: e :> es => Reader r e -> (r -> a) -> Eff es a
- local :: e1 :> es => Reader r e1 -> (r -> r) -> Eff es a -> Eff es a
- newtype HandleReader h e = UnsafeMkHandleReader (State (h e) e)
- mapHandleReader :: forall h e es. (Handle h, e :> es) => HandleReader h e -> HandleReader h es
- localHandle :: (e :> es, Handle h) => HandleReader h e -> (h es -> h es) -> Eff es r -> Eff es r
- askHandle :: (e :> es, Handle h) => HandleReader h e -> Eff es (h es)
- runHandleReader :: (e1 :> es, Handle h) => h e1 -> (forall e. HandleReader h e -> Eff (e :& es) r) -> Eff es r
- newtype ConstEffect r e = MkConstEffect r
- runConstEffect :: r -> (forall e. ConstEffect r e -> Eff (e :& es) a) -> Eff es a
Documentation
Instances
Handle (ConstEffect r :: Effects -> Type) Source # | |
Defined in Bluefin.Internal Methods mapHandle :: forall (e :: Effects) (es :: Effects). e :> es => ConstEffect r e -> ConstEffect r es Source # |
newtype Eff (es :: Effects) a Source #
Constructors
UnsafeMkEff | |
Fields
|
newtype EffReader r es a Source #
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
.
Constructors
MkEffReader | |
Fields
|
Instances
e :> es => MonadBaseControl IO (EffReader (IOE e) es) Source # | |
e :> es => MonadBase IO (EffReader (IOE e) es) Source # | |
e :> es => MonadFail (EffReader (Exception String e) es) Source # | |
e :> es => MonadIO (EffReader (IOE e) es) Source # | |
Applicative (EffReader r es) Source # | |
Defined in Bluefin.Internal Methods pure :: a -> EffReader r es a # (<*>) :: EffReader r es (a -> b) -> EffReader r es a -> EffReader r es b # liftA2 :: (a -> b -> c) -> EffReader r es a -> EffReader r es b -> EffReader r es c # (*>) :: EffReader r es a -> EffReader r es b -> EffReader r es b # (<*) :: EffReader r es a -> EffReader r es b -> EffReader r es a # | |
Functor (EffReader r es) Source # | |
Monad (EffReader r es) Source # | |
e :> es => MonadUnliftIO (EffReader (IOE e) es) Source # | You probably want to use |
Defined in Bluefin.Internal | |
type StM (EffReader (IOE e) es) a Source # | |
Defined in Bluefin.Internal |
runEffReader :: r -> EffReader r es a -> Eff es a Source #
Arguments
:: e2 :> es | |
=> ((forall r. (forall e1. IOE e1 -> Eff (e1 :& es) r) -> IO r) -> IO a) | Continuation with the unlifting function in scope. |
-> IOE e2 | |
-> Eff es a |
Deprecated. Use withEffToIO_
instead.
Arguments
:: e :> es | |
=> IOE e | |
-> ((forall r. Eff es r -> IO r) -> IO a) | Continuation with the unlifting function in scope. |
-> Eff es a |
This is equivalent to the withRunInIO
method of
MonadUnliftIO
, but written in Bluefin-style.
race :: e2 :> es => (forall e. IOE e -> Eff (e :& es) a) -> (forall e. IOE e -> Eff (e :& es) a) -> IOE e2 -> Eff es a Source #
Arguments
:: 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 | ͘ |
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
).
receiveStream :: (forall e. Consume a e -> Eff (e :& es) r) -> (forall e. Stream a e -> Eff (e :& es) r) -> Eff es r Source #
Old name for consumeStream
. receiveStream
will be deprecated
in a future version.
hoistReader :: (forall b. m b -> n b) -> ReaderT r m a -> ReaderT r n a Source #
unsafeRemoveEff :: Eff (e :& es) a -> Eff es a Source #
This function is really very unsafe and for internal use only.
Unlike the similarly-named unsafeEff_
function from effectful
,
which is provided for use in user code, this function must never be
used in user code.
runPureEff :: (forall es. Eff es a) -> a Source #
Run an Eff
that doesn't contain any unhandled effects.
Used to define handlers of compound effects.
Deprecated. Use useImplUnder
instead.
data StateSource (e :: Effects) Source #
Handle to a capability to create strict mutable state handles
Constructors
StateSource |
newtype Exception exn (e :: Effects) Source #
Handle to an exception of type exn
Constructors
UnsafeMkException (forall a. exn -> IO a) |
newtype State s (e :: Effects) Source #
A handle to a strict mutable state of type s
Constructors
UnsafeMkState (IORef s) |
newtype Coroutine a b (e :: Effects) Source #
A handle to a coroutine that yields values of type a
and then
expects values of type b
.
Constructors
MkCoroutine (a -> Eff e b) |
type Stream a = Coroutine a () Source #
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 ()
.
class Handle (h :: Effects -> Type) where Source #
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 :: forall e'. String -> Int -> Eff (e' :& 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 themeselves handles and
apply useImplUnder
to all the fields that are dynamic effects:
instance Handle Application where mapHandle MkApplication { queryDatabase = q, applicationState = a, logger = l } = MkApplication { queryDatabase = s i -> useImplUnder (q s i), applicationState = mapHandle a, logger = mapHandle l }
Methods
mapHandle :: e :> es => h e -> h es Source #
Used to create compound effects, i.e. handles that contain other handles.
Instances
class (es1 :: Effects) :> (es2 :: Effects) Source #
Effect subset constraint
Instances
e :> e Source # | A set of effects |
Defined in Bluefin.Internal | |
e :> (e :& es) Source # |
|
Defined in Bluefin.Internal | |
e :> es => e :> (x :& es) Source # | If |
Defined in Bluefin.Internal |
>>> 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"
Arguments
:: forall exn (es :: Effects) a. (forall e. Exception exn e -> Eff (e :& es) a) | |
-> Eff es (Either exn a) |
|
>>> runPureEff $ try $ \e -> do throw e 42 pure "No exception thrown" Left 42
Arguments
:: forall exn (es :: Effects) a. (exn -> Eff es a) | If the exception is thrown, apply this handler |
-> (forall e. Exception exn e -> Eff (e :& es) a) | |
-> Eff es a |
handle
, but with the argument order swapped
>>> runPureEff $ handle (pure . show) $ \e -> do throw e 42 pure "No exception thrown" "42"
Arguments
:: forall ex es e1 e2 r. (e1 :> es, e2 :> es, Exception ex) | |
=> IOE e1 | |
-> Exception ex e2 | |
-> Eff es r | |
-> Eff es r | ͘ |
Rethrow an exception raised by an IO
action as a Bluefin
exception.
runEff
$ \io -> do r <-try
$ \ex -> do rethrowIO @IOException
io ex $ do effIO io (readFile
"/tmp/doesnt-exist")effIO
io $ putStrLn $ case r of Left e -> "Caught IOException:\n" ++ show e Right contents -> contents
Caught IOException: /tmp/doesnt-exist: openFile: does not exist (No such file or directory)
Arguments
:: Eff es a | Acquire the resource |
-> (a -> Eff es ()) | Release the resource |
-> (a -> Eff es b) | Run the body |
-> Eff es b |
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.
, whose
documentation you can inspect for further details.bracket
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 beforebracket
exits. This is inherited from the fact thatEff
is a wrapper aroundIO
.
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.
>>> runPureEff $ runState 10 $ \st -> do n <- get st pure (2 * n) (20,10)
Arguments
:: e :> es | |
=> State s e | |
-> s | The new value of the state. The new value is forced before writing it to the state. |
-> Eff es () |
Set the value of the state
>>> runPureEff $ runState 10 $ \st -> do put st 30 ((), 30)
Arguments
:: e :> es | |
=> State s e | |
-> (s -> s) | Apply this function to the state. The new value of the state is forced before writing it to the state. |
-> Eff es () |
>>> runPureEff $ runState 10 $ \st -> do modify st (* 2) ((), 20)
data MyException where Source #
Constructors
MyException :: e -> Unique -> MyException |
Instances
Exception MyException Source # | |
Defined in Bluefin.Internal Methods toException :: MyException -> SomeException # fromException :: SomeException -> Maybe MyException # displayException :: MyException -> String # | |
Show MyException Source # | |
Defined in Bluefin.Internal Methods showsPrec :: Int -> MyException -> ShowS # show :: MyException -> String # showList :: [MyException] -> ShowS # |
Arguments
:: (forall e. StateSource e -> Eff (e :& es) a) | |
-> Eff es a | ͘ |
runPureEff
$withStateSource
$ \source -> do n <-newState
source 5 total <- newState source 0withJump
$ \done -> forever $ do n' <-get
nmodify
total (+ n') when (n' == 0) $jumpTo
done modify n (subtract 1) get total 15
Arguments
:: StateSource e | |
-> s | The initial value for the state handle |
-> Eff es (State s e) | A new state handle |
Arguments
:: s | Initial state |
-> (forall e. State s e -> Eff (e :& es) a) | Stateful computation |
-> Eff es (a, s) | Result and final state |
>>> runPureEff $ runState 10 $ \st -> do n <- get st pure (2 * n) (20,10)
Yield an element to the stream.
>>> runPureEff $ yieldToList $ \y -> do yield y 1 yield y 2 yield y 100 ([1,2,100], ())
handleCoroutine :: (a -> Eff es b) -> (z -> Eff es r) -> (forall e1. Coroutine a b e1 -> Eff (e1 :& es) z) -> Eff es r Source #
Arguments
:: (forall e1. Coroutine a b e1 -> Eff (e1 :& es) r) | |
-> (a -> Eff es b) | Apply this effectful function for each element of the coroutine |
-> Eff es r |
Apply an effectful function to each element yielded to the stream.
>>> runPureEff $ yieldToList $ \y -> do for_ [0 .. 4] $ \i -> do yield y i yield y (i * 10) ([0, 0, 1, 10, 2, 20, 3, 30], ())
Ignore all elements yielded to the stream.
>>> runPureEff $ ignoreStream $ \y -> do for_ [0 .. 4] $ \i -> do yield y i yield y (i * 10) pure 42 42
Arguments
:: (Foldable t, e1 :> es) | |
=> t a | Yield all these values from the stream |
-> Stream a e1 | |
-> Eff es () |
>>> runPureEff $ yieldToList $ inFoldable [1, 2, 100] ([1, 2, 100], ())
Arguments
:: e2 :> es | |
=> (forall e1. Stream a e1 -> Eff (e1 :& es) r) | ͘ |
-> Stream (Int, a) e2 | |
-> Eff es r |
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")], ())
Arguments
:: e2 :> es | |
=> Int | Initial value |
-> (forall e1. Stream a e1 -> Eff (e1 :& es) r) | |
-> Stream (Int, a) e2 | |
-> Eff es r |
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")], ())
type EarlyReturn = Exception Source #
Arguments
:: (forall e. EarlyReturn r e -> Eff (e :& es) r) | |
-> Eff es r | ͘ |
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"
Arguments
:: e :> es | |
=> EarlyReturn r e | |
-> r | Return early to the handler, with this value. |
-> Eff es a |
>>> 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"
Arguments
:: s | Initial state |
-> (forall e. State s e -> Eff (e :& es) a) | Stateful computation |
-> Eff es a | Result |
>>> runPureEff $ evalState 10 $ \st -> do n <- get st pure (2 * n) 20
Arguments
:: s | Initial state |
-> (forall e. State s e -> Eff (e :& es) (s -> a)) | Stateful computation |
-> Eff es a | Result |
>>> runPureEff $ withState 10 $ \st -> do n <- get st pure (s -> (2 * n, s)) (20,10)
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 Source #
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 Source #
Arguments
:: (forall e1. Stream a e1 -> Eff (e1 :& es) r) | |
-> Eff es ([a], r) | Yielded elements and final result |
Gather all yielded elements into a list.
>>> runPureEff $ yieldToList $ \y -> do yield y 1 yield y 2 yield y 100 ([1,2,100], ())
>>> runPureEff $ withYieldToList $ \y -> do yield y 1 yield y 2 yield y 100 pure length 3
Arguments
:: (forall e. Stream a e -> Eff (e :& es) r) | |
-> Eff es ([a], r) | Yielded elements in reverse order, and final result |
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], ())
Arguments
:: e2 :> es | |
=> (forall e1. Stream (Maybe a) e1 -> Eff (e1 :& es) r) | Input stream |
-> Stream a e2 | |
-> Eff es r |
Remove Nothing
elements from a stream.
type Jump = EarlyReturn () Source #
data IOE (e :: Effects) Source #
Handle that allows you to run IO
operations
Constructors
MkIOE |
Instances
Handle IOE Source # | |
e :> es => MonadBaseControl IO (EffReader (IOE e) es) Source # | |
e :> es => MonadBase IO (EffReader (IOE e) es) Source # | |
e :> es => MonadIO (EffReader (IOE e) es) Source # | |
e :> es => MonadUnliftIO (EffReader (IOE e) es) Source # | You probably want to use |
Defined in Bluefin.Internal | |
type StM (EffReader (IOE e) es) a Source # | |
Defined in Bluefin.Internal |
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)) Source #
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)) Source #
Read the value. Note that ask
has the property that these two
operations are always equivalent:
do r1 <- ask re r2 <- ask re pure (r1, r2)
do r <- ask re pure (r, r)
Read the value modified by a function
newtype HandleReader h e Source #
Constructors
UnsafeMkHandleReader (State (h e) e) |
Instances
Handle h => Handle (HandleReader h) Source # | |
Defined in Bluefin.Internal Methods mapHandle :: forall (e :: Effects) (es :: Effects). e :> es => HandleReader h e -> HandleReader h es Source # |
Arguments
:: forall h e es. (Handle h, e :> es) | |
=> HandleReader h e | |
-> HandleReader h es | ͘ |
Arguments
:: (e :> es, Handle h) | |
=> HandleReader h e | |
-> (h es -> h es) | |
-> Eff es r | |
-> Eff es r | ͘ |
newtype ConstEffect r e Source #
Constructors
MkConstEffect r |
Instances
Handle (ConstEffect r :: Effects -> Type) Source # | |
Defined in Bluefin.Internal Methods mapHandle :: forall (e :: Effects) (es :: Effects). e :> es => ConstEffect r e -> ConstEffect r es Source # |
Arguments
:: r | |
-> (forall e. ConstEffect r e -> Eff (e :& es) a) | |
-> Eff es a | ͘ |