| 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
- 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
- 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
- useImpl :: e :> es => Eff e r -> Eff es r
- useImplIn :: e :> es => (t -> Eff (es :& e) r) -> t -> Eff es r
- data StateSource (st :: Effects) = StateSource
- newtype Exception e (ex :: Effects) = UnsafeMkException (forall a. e -> IO a)
- newtype State s (st :: Effects) = UnsafeMkState (IORef s)
- newtype Coroutine a b (s :: Effects) = MkCoroutine (a -> Eff s b)
- type Stream 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
- class (es1 :: Effects) :> (es2 :: Effects)
- throw :: ex :> es => Exception e ex -> e -> 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 e (es :: Effects) a. (forall ex. Exception e ex -> Eff (ex :& es) a) -> Eff es (Either e a)
- handle :: forall e (es :: Effects) a. (e -> Eff es a) -> (forall ex. Exception e ex -> Eff (ex :& es) a) -> Eff es a
- catch :: forall e (es :: Effects) a. (forall ex. Exception e ex -> Eff (ex :& es) a) -> (e -> Eff es a) -> Eff es a
- bracket :: Eff es a -> (a -> Eff es ()) -> (a -> Eff es b) -> Eff es b
- get :: st :> es => State s st -> Eff es s
- put :: st :> es => State s st -> s -> Eff es ()
- modify :: st :> es => State s st -> (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 st. State s st -> Eff (st :& 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
- 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
- type EarlyReturn = Exception
- withEarlyReturn :: (forall er. EarlyReturn r er -> Eff (er :& es) r) -> Eff es r
- returnEarly :: er :> es => EarlyReturn r er -> r -> Eff es a
- evalState :: s -> (forall st. State s st -> Eff (st :& es) a) -> Eff es a
- withState :: s -> (forall st. State s st -> Eff (st :& 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 j. Jump j -> Eff (j :& es) ()) -> Eff es ()
- jumpTo :: j :> es => Jump j -> Eff es a
- unwrap :: j :> es => Jump j -> 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
- 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 :: Effects) = MkReader r
- runReader :: r -> (forall e. Reader r e -> Eff (e :& es) a) -> Eff es a
- ask :: e :> es => Reader r e -> Eff es r
Documentation
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 # | |
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 #
hoistReader :: (forall b. m b -> n b) -> ReaderT r m a -> ReaderT r n a Source #
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.
data StateSource (st :: Effects) Source #
Handle to a capability to create strict mutable state handles
Constructors
| StateSource |
newtype Exception e (ex :: Effects) Source #
Handle to an exception of type e
Constructors
| UnsafeMkException (forall a. e -> IO a) |
newtype State s (st :: Effects) Source #
A handle to a strict mutable state of type a
Constructors
| UnsafeMkState (IORef s) |
newtype Coroutine a b (s :: Effects) Source #
A handle to a coroutine that expects values of type a and then
yields values of type b.
Constructors
| MkCoroutine (a -> Eff s 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 expects values of type
() and then yields values of type a.
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 :: 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 fmaps before useImpl.
Methods
mapHandle :: e :> es => h e -> h es Source #
Used to create compound effects, i.e. handles that contain other handles.
Instances
| Handle Application Source # | |
Defined in Bluefin.Internal.Examples Methods mapHandle :: forall (e :: Effects) (es :: Effects). e :> es => Application e -> Application es Source # | |
| Handle (Exception s) Source # | |
| Handle (Reader r) Source # | |
| Handle (State s) Source # | |
| Handle (Writer w) Source # | |
| Handle (Coroutine a b) Source # | |
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 e (es :: Effects) a. (forall ex. Exception e ex -> Eff (ex :& es) a) | |
| -> Eff es (Either e a) |
|
>>> runPureEff $ try $ \e -> do
throw e 42
pure "No exception thrown"
Left 42
Arguments
| :: forall e (es :: Effects) a. (e -> Eff es a) | If the exception is thrown, apply this handler |
| -> (forall ex. Exception e ex -> Eff (ex :& 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"
bracket :: Eff es a -> (a -> Eff es ()) -> (a -> Eff es b) -> Eff es b Source #
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
>>> runPureEff $ runState 10 $ \st -> do
n <- get st
pure (2 * n)
(20,10)
Arguments
| :: st :> es | |
| => State s st | |
| -> 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
| :: st :> es | |
| => State s st | |
| -> (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 <-newStatesource 5 total <- newState source 0withJump$ \done -> forever $ do n' <-getnmodifytotal (+ n') when (n' == 0) $jumpTodone 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 st. State s st -> Eff (st :& 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)
>>> 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 |
>>> 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], ())
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 er. EarlyReturn r er -> Eff (er :& 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
| :: er :> es | |
| => EarlyReturn r er | |
| -> 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 st. State s st -> Eff (st :& 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 st. State s st -> Eff (st :& 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 |
>>> 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
| 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 # | |
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 #