bluefin-internal-0.0.3.0: The Bluefin effect system, internals
Safe HaskellSafe-Inferred
LanguageHaskell2010

Bluefin.Internal

Synopsis

Documentation

data Effects Source #

Constructors

Union Effects Effects 

type (:&) = Union infixr 9 Source #

type (:&) :: Effects -> Effects -> Effects

Union of effects

newtype Eff (es :: Effects) a Source #

Constructors

UnsafeMkEff 

Fields

Instances

Instances details
Applicative (Eff es) Source # 
Instance details

Defined in Bluefin.Internal

Methods

pure :: a -> Eff es a #

(<*>) :: Eff es (a -> b) -> Eff es a -> Eff es b #

liftA2 :: (a -> b -> c) -> Eff es a -> Eff es b -> Eff es c #

(*>) :: Eff es a -> Eff es b -> Eff es b #

(<*) :: Eff es a -> Eff es b -> Eff es a #

Functor (Eff es) Source # 
Instance details

Defined in Bluefin.Internal

Methods

fmap :: (a -> b) -> Eff es a -> Eff es b #

(<$) :: a -> Eff es b -> Eff es a #

Monad (Eff es) Source # 
Instance details

Defined in Bluefin.Internal

Methods

(>>=) :: Eff es a -> (a -> Eff es b) -> Eff es b #

(>>) :: Eff es a -> Eff es b -> Eff es b #

return :: a -> Eff es a #

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

Instances details
e :> es => MonadBaseControl IO (EffReader (IOE e) es) Source # 
Instance details

Defined in Bluefin.Internal

Associated Types

type StM (EffReader (IOE e) es) a #

Methods

liftBaseWith :: (RunInBase (EffReader (IOE e) es) IO -> IO a) -> EffReader (IOE e) es a #

restoreM :: StM (EffReader (IOE e) es) a -> EffReader (IOE e) es a #

e :> es => MonadBase IO (EffReader (IOE e) es) Source # 
Instance details

Defined in Bluefin.Internal

Methods

liftBase :: IO α -> EffReader (IOE e) es α #

e :> es => MonadFail (EffReader (Exception String e) es) Source # 
Instance details

Defined in Bluefin.Internal

Methods

fail :: String -> EffReader (Exception String e) es a #

e :> es => MonadIO (EffReader (IOE e) es) Source # 
Instance details

Defined in Bluefin.Internal

Methods

liftIO :: IO a -> EffReader (IOE e) es a #

Applicative (EffReader r es) Source # 
Instance details

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 # 
Instance details

Defined in Bluefin.Internal

Methods

fmap :: (a -> b) -> EffReader r es a -> EffReader r es b #

(<$) :: a -> EffReader r es b -> EffReader r es a #

Monad (EffReader r es) Source # 
Instance details

Defined in Bluefin.Internal

Methods

(>>=) :: EffReader r es a -> (a -> EffReader r es b) -> EffReader r es b #

(>>) :: EffReader r es a -> EffReader r es b -> EffReader r es b #

return :: a -> EffReader r es a #

e :> es => MonadUnliftIO (EffReader (IOE e) es) Source # 
Instance details

Defined in Bluefin.Internal

Methods

withRunInIO :: ((forall a. EffReader (IOE e) es a -> IO a) -> IO b) -> EffReader (IOE e) es b #

type StM (EffReader (IOE e) es) a Source # 
Instance details

Defined in Bluefin.Internal

type StM (EffReader (IOE e) es) a = a

effReader :: (r -> Eff es a) -> EffReader r es a Source #

runEffReader :: r -> EffReader r es a -> Eff es a Source #

withEffToIO 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 

hoistReader :: (forall b. m b -> n b) -> ReaderT r m a -> ReaderT r n a Source #

withMonadIO Source #

Arguments

:: e :> es 
=> IOE e 
-> (forall m. MonadIO m => m r)

MonadIO operation

-> Eff es r

MonadIO operation run in Eff

Run MonadIO operations in Eff.

>>> runEff $ \io -> withMonadIO io $ liftIO $ do
      putStrLn "Hello world!"
Hello, world!

withMonadFail Source #

Arguments

:: e :> es 
=> Exception String e

Exception to throw on fail

-> (forall m. MonadFail m => m r)

MonadFail operation

-> Eff es r

MonadFail operation run in Eff

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"

unsafeRemoveEff :: Eff (e :& es) a -> Eff es a Source #

runPureEff :: (forall es. Eff es a) -> a Source #

Run an Eff that doesn't contain any unhandled effects.

weakenEff :: (t `In` t') -> Eff t r -> Eff t' r Source #

insertFirst :: Eff b r -> Eff (c1 :& b) r Source #

insertSecond :: Eff (c1 :& b) r -> Eff (c1 :& (c2 :& b)) r Source #

assoc1Eff :: Eff ((a :& b) :& c) r -> Eff (a :& (b :& c)) r Source #

pushFirst :: Eff a r -> Eff (a :& b) r Source #

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

Exception (forall a. e -> IO a) 

Instances

Instances details
e :> es => MonadFail (EffReader (Exception String e) es) Source # 
Instance details

Defined in Bluefin.Internal

Methods

fail :: String -> EffReader (Exception String e) es 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

UnsafeMkCoroutine (a -> IO 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.

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

Constructors

In# (# #) 

eq :: (# #) -> a `In` a Source #

fstI :: (# #) -> a `In` (a :& b) Source #

sndI :: (# #) -> a `In` (b :& a) Source #

cmp :: (a `In` b) -> (b `In` c) -> a `In` c Source #

bimap :: (a `In` b) -> (c `In` d) -> (a :& c) `In` (b :& d) Source #

assoc1 :: (# #) -> ((a :& b) :& c) `In` (a :& (b :& c)) Source #

drop :: (a `In` b) -> a `In` (c :& b) Source #

here :: (a `In` b) -> a `In` (b :& c) Source #

w :: ((a :& b) `In` c) -> a `In` c Source #

w2 :: ((b :& a) `In` c) -> a `In` c Source #

b2 :: (a `In` b) -> (a :& c) `In` (b :& c) Source #

b :: (a `In` b) -> (c :& a) `In` (c :& b) Source #

class (es1 :: Effects) :> (es2 :: Effects) Source #

Effect subset constraint

Instances

Instances details
e :> e Source #

A set of effects e is a subset of itself

Instance details

Defined in Bluefin.Internal

e :> (e :& es) Source #

e is a subset of a larger set e :& es

Instance details

Defined in Bluefin.Internal

e :> es => e :> (x :& es) Source #

If e is subset of es then e is a subset of a larger set, x :& es

Instance details

Defined in Bluefin.Internal

throw Source #

Arguments

:: ex :> es 
=> Exception e ex 
-> e

Value to throw

-> Eff es a 
>>> 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"

has :: forall a b. a :> b => a `In` b Source #

data Dict c where Source #

Constructors

Dict :: forall c. c => Dict c 

have :: forall a b. (a `In` b) -> Dict (a :> b) Source #

try Source #

Arguments

:: forall e (es :: Effects) a. (forall ex. Exception e ex -> Eff (ex :& es) a) 
-> Eff es (Either e a)

Left if the exception was thrown, Right otherwise

>>> runPureEff $ try $ \e -> do
      throw e 42
      pure "No exception thrown"
Left 42

handle Source #

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"

catch Source #

Arguments

:: forall e (es :: Effects) a. (forall ex. Exception e ex -> Eff (ex :& es) a) 
-> (e -> Eff es a)

If the exception is thrown, apply this handler

-> Eff es a 

get Source #

Arguments

:: st :> es 
=> State s st 
-> Eff es s

The current value of the state

>>> runPureEff $ runState 10 $ \st -> do
      n <- get st
      pure (2 * n)
(20,10)

put Source #

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)

modify Source #

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)

withScopedException_ :: ((forall a. e -> IO a) -> IO r) -> IO (Either e r) Source #

withStateSource Source #

Arguments

:: (forall e. StateSource e -> Eff (e :& es) a) 
-> Eff es a

͘

runPureEff $ withStateSource $ \source -> do
  n <- newState source 5
  total <- newState source 0

  withJump $ \done -> forever $ do
    n' <- get n
    modify total (+ n')
    when (n' == 0) $ jumpTo done
    modify n (subtract 1)

  get total
15

newState Source #

Arguments

:: StateSource e 
-> s

The initial value for the state handle

-> Eff es (State s e)

A new state handle

runPureEff $ withStateSource $ \source -> do
  n <- newState source 5
  total <- newState source 0

  withJump $ \done -> forever $ do
    n' <- get n
    modify total (+ n')
    when (n' == 0) $ jumpTo done
    modify n (subtract 1)

  get total
15

runState Source #

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)

yieldCoroutine Source #

Arguments

:: e1 :> es 
=> Coroutine a b e1 
-> a

͘

-> Eff es b 

yield Source #

Arguments

:: e1 :> es 
=> Stream a e1 
-> a

Yield this value from the stream

-> Eff es () 
>>> 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 #

forEach 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], ())

inFoldable Source #

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], ())

enumerate Source #

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")], ())

enumerateFrom Source #

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")], ())

withEarlyReturn 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"

returnEarly Source #

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"

evalState Source #

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

withState Source #

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)

data Compound e1 e2 ss where Source #

Constructors

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

compound Source #

Arguments

:: h1 e1 
-> h2 e2

͘

-> Compound h1 h2 (e1 :& e2) 

inComp :: forall a b c r. a :> b => b :> c => (a :> c => r) -> r Source #

withCompound Source #

Arguments

:: 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 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 #

putC :: forall ss es e. ss :> es => Compound e (State Int) ss -> Int -> Eff es () Source #

getC :: forall ss es e. ss :> es => Compound e (State Int) ss -> Eff es Int Source #

runCompound Source #

Arguments

:: e1 s1 
-> e2 s2

͘

-> (forall es'. Compound e1 e2 es' -> Eff (es' :& es) r) 
-> Eff (s1 :& (s2 :& es)) r 

yieldToList 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], ())

yieldToReverseList Source #

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], ())

mapStream Source #

Arguments

:: e2 :> es 
=> (a -> b)

Apply this function to all elements of the input stream.

-> (forall e1. Stream a e1 -> Eff (e1 :& es) r)

Input stream

-> Stream b e2 
-> Eff es r 

mapMaybe Source #

Arguments

:: e2 :> es 
=> (a -> Maybe b)

Yield from the output stream all of the elemnts of the input stream for which this function returns Just

-> (forall e1. Stream a e1 -> Eff (e1 :& es) r)

Input stream

-> Stream b e2 
-> Eff es r 

catMaybes Source #

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.

withJump Source #

Arguments

:: (forall j. Jump j -> Eff (j :& es) ()) 
-> Eff es ()

͘

jumpTo Source #

Arguments

:: j :> es 
=> Jump j 
-> Eff es a

͘

unwrap :: j :> es => Jump j -> Maybe a -> Eff es a Source #

data IOE (e :: Effects) Source #

Handle that allows you to run IO operations

Constructors

MkIOE 

Instances

Instances details
e :> es => MonadBaseControl IO (EffReader (IOE e) es) Source # 
Instance details

Defined in Bluefin.Internal

Associated Types

type StM (EffReader (IOE e) es) a #

Methods

liftBaseWith :: (RunInBase (EffReader (IOE e) es) IO -> IO a) -> EffReader (IOE e) es a #

restoreM :: StM (EffReader (IOE e) es) a -> EffReader (IOE e) es a #

e :> es => MonadBase IO (EffReader (IOE e) es) Source # 
Instance details

Defined in Bluefin.Internal

Methods

liftBase :: IO α -> EffReader (IOE e) es α #

e :> es => MonadIO (EffReader (IOE e) es) Source # 
Instance details

Defined in Bluefin.Internal

Methods

liftIO :: IO a -> EffReader (IOE e) es a #

e :> es => MonadUnliftIO (EffReader (IOE e) es) Source # 
Instance details

Defined in Bluefin.Internal

Methods

withRunInIO :: ((forall a. EffReader (IOE e) es a -> IO a) -> IO b) -> EffReader (IOE e) es b #

type StM (EffReader (IOE e) es) a Source # 
Instance details

Defined in Bluefin.Internal

type StM (EffReader (IOE e) es) a = a

effIO Source #

Arguments

:: e :> es 
=> IOE e 
-> IO a 
-> Eff es a

͘

Run an IO operation in Eff

>>> runEff $ \io -> do
      effIO io (putStrLn "Hello world!")
Hello, world!

runEff Source #

Arguments

:: (forall e es. IOE e -> Eff (e :& es) a) 
-> IO a

͘

Run an Eff whose only unhandled effect is IO.

>>> runEff $ \io -> do
      effIO io (putStrLn "Hello world!")
Hello, world!

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 #

newtype Writer w e Source #

Constructors

Writer (Stream w e) 

runWriter Source #

Arguments

:: Monoid w 
=> (forall e. Writer w e -> Eff (e :& es) r)

͘

-> Eff es (r, w) 
>>> getAny $ snd $ runPureEff $ runWriter $ \w -> do
      -- Non-empty list (the tell event does happen)
      for_ [1 .. 10] $ \_ -> tell w (Any True)
True

execWriter Source #

Arguments

:: Monoid w 
=> (forall e. Writer w e -> Eff (e :& es) r)

͘

-> Eff es w 
>>> getAny $ runPureEff $ execWriter $ \w -> do
      -- Non-empty list (the tell event does happen)
      for_ [1 .. 10] $ \_ -> tell w (Any True)
True
>>> getAny $ runPureEff $ execWriter $ \w -> do
      -- Empty list (the tell event does not happen)
      for_ [] $ \_ -> tell w (Any True)
False

tell Source #

Arguments

:: e :> es 
=> Writer w e 
-> w

͘

-> Eff es () 
>>> getAny $ runPureEff $ execWriter $ \w -> do
      -- Non-empty list (the tell event does happen)
      for_ [1 .. 10] $ \_ -> tell w (Any True)
True

newtype Reader r (e :: Effects) Source #

Constructors

MkReader r 

runReader Source #

Arguments

:: r

͘

-> (forall e. Reader r e -> Eff (e :& es) a) 
-> Eff es a 

ask :: e :> es => Reader r e -> Eff es r Source #