packages feed

bluefin-internal 0.0.6.0 → 0.0.6.1

raw patch · 4 files changed

+95/−36 lines, 4 filesPVP: major bump suggested

API removals or changes: PVP suggests a major version bump

API changes (from Hackage documentation)

+ Bluefin.Internal.Examples: polymorphicBracket :: st :> es => State (Integer, Bool) st -> Eff es () -> Eff es ()
+ Bluefin.Internal.Examples: polymorphicBracketExample1 :: (Integer, Bool)
+ Bluefin.Internal.Examples: polymorphicBracketExample2 :: (Integer, Bool)
- Bluefin.Internal: MkCoroutine :: (a -> Eff s b) -> Coroutine a b (s :: Effects)
+ Bluefin.Internal: MkCoroutine :: (a -> Eff e b) -> Coroutine a b (e :: Effects)
- Bluefin.Internal: StateSource :: StateSource (st :: Effects)
+ Bluefin.Internal: StateSource :: StateSource (e :: Effects)
- Bluefin.Internal: UnsafeMkException :: (forall a. e -> IO a) -> Exception e (ex :: Effects)
+ Bluefin.Internal: UnsafeMkException :: (forall a. exn -> IO a) -> Exception exn (e :: Effects)
- Bluefin.Internal: UnsafeMkState :: IORef s -> State s (st :: Effects)
+ Bluefin.Internal: UnsafeMkState :: IORef s -> State s (e :: Effects)
- Bluefin.Internal: catch :: forall e (es :: Effects) a. (forall ex. Exception e ex -> Eff (ex :& es) a) -> (e -> Eff es a) -> Eff es a
+ Bluefin.Internal: catch :: forall exn (es :: Effects) a. (forall e. Exception exn e -> Eff (e :& es) a) -> (exn -> Eff es a) -> Eff es a
- Bluefin.Internal: data StateSource (st :: Effects)
+ Bluefin.Internal: data StateSource (e :: Effects)
- Bluefin.Internal: evalState :: s -> (forall st. State s st -> Eff (st :& es) a) -> Eff es a
+ Bluefin.Internal: evalState :: s -> (forall e. State s e -> Eff (e :& es) a) -> Eff es a
- Bluefin.Internal: get :: st :> es => State s st -> Eff es s
+ Bluefin.Internal: get :: e :> es => State s e -> Eff es s
- Bluefin.Internal: handle :: forall e (es :: Effects) a. (e -> Eff es a) -> (forall ex. Exception e ex -> Eff (ex :& es) a) -> Eff es a
+ Bluefin.Internal: handle :: forall exn (es :: Effects) a. (exn -> Eff es a) -> (forall e. Exception exn e -> Eff (e :& es) a) -> Eff es a
- Bluefin.Internal: jumpTo :: j :> es => Jump j -> Eff es a
+ Bluefin.Internal: jumpTo :: e :> es => Jump e -> Eff es a
- Bluefin.Internal: modify :: st :> es => State s st -> (s -> s) -> Eff es ()
+ Bluefin.Internal: modify :: e :> es => State s e -> (s -> s) -> Eff es ()
- Bluefin.Internal: newtype Coroutine a b (s :: Effects)
+ Bluefin.Internal: newtype Coroutine a b (e :: Effects)
- Bluefin.Internal: newtype Exception e (ex :: Effects)
+ Bluefin.Internal: newtype Exception exn (e :: Effects)
- Bluefin.Internal: newtype State s (st :: Effects)
+ Bluefin.Internal: newtype State s (e :: Effects)
- Bluefin.Internal: put :: st :> es => State s st -> s -> Eff es ()
+ Bluefin.Internal: put :: e :> es => State s e -> s -> Eff es ()
- Bluefin.Internal: returnEarly :: er :> es => EarlyReturn r er -> r -> Eff es a
+ Bluefin.Internal: returnEarly :: e :> es => EarlyReturn r e -> r -> Eff es a
- Bluefin.Internal: runState :: s -> (forall st. State s st -> Eff (st :& es) a) -> Eff es (a, s)
+ Bluefin.Internal: runState :: s -> (forall e. State s e -> Eff (e :& es) a) -> Eff es (a, s)
- Bluefin.Internal: try :: forall e (es :: Effects) a. (forall ex. Exception e ex -> Eff (ex :& es) a) -> Eff es (Either e a)
+ Bluefin.Internal: try :: forall exn (es :: Effects) a. (forall e. Exception exn e -> Eff (e :& es) a) -> Eff es (Either exn a)
- Bluefin.Internal: unwrap :: j :> es => Jump j -> Maybe a -> Eff es a
+ Bluefin.Internal: unwrap :: e :> es => Jump e -> Maybe a -> Eff es a
- Bluefin.Internal: withEarlyReturn :: (forall er. EarlyReturn r er -> Eff (er :& es) r) -> Eff es r
+ Bluefin.Internal: withEarlyReturn :: (forall e. EarlyReturn r e -> Eff (e :& es) r) -> Eff es r
- Bluefin.Internal: withJump :: (forall j. Jump j -> Eff (j :& es) ()) -> Eff es ()
+ Bluefin.Internal: withJump :: (forall e. Jump e -> Eff (e :& es) ()) -> Eff es ()

Files

CHANGELOG.md view
@@ -1,3 +1,7 @@+## 0.0.6.1++* Documentation improvements+ ## 0.0.6.0  * Add `withYieldToList`
bluefin-internal.cabal view
@@ -1,6 +1,6 @@ cabal-version:      3.0 name:               bluefin-internal-version:            0.0.6.0+version:            0.0.6.1 license:            MIT license-file:       LICENSE author:             Tom Ellis@@ -77,7 +77,7 @@     default-language: Haskell2010     hs-source-dirs: src     build-depends:-      base >= 4.12 && < 4.20,+      base >= 4.12 && < 4.21,       unliftio-core < 0.3,       transformers < 0.7,       transformers-base < 0.5,
src/Bluefin/Internal.hs view
@@ -35,6 +35,7 @@ type (:&) = Union  type role Eff nominal representational+ newtype Eff (es :: Effects) a = UnsafeMkEff {unsafeUnEff :: IO a}   deriving stock (Functor)   deriving newtype (Applicative, Monad)@@ -184,17 +185,17 @@ useImplIn f h = inContext (f h)  -- | Handle to a capability to create strict mutable state handles-data StateSource (st :: Effects) = StateSource+data StateSource (e :: Effects) = StateSource --- | Handle to an exception of type @e@-newtype Exception e (ex :: Effects) = UnsafeMkException (forall a. e -> IO a)+-- | Handle to an exception of type @exn@+newtype Exception exn (e :: Effects) = UnsafeMkException (forall a. exn -> IO a) --- | A handle to a strict mutable state of type @a@-newtype State s (st :: Effects) = UnsafeMkState (IORef s)+-- | A handle to a strict mutable state of type @s@+newtype State s (e :: 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)+newtype Coroutine a b (e :: Effects) = MkCoroutine (a -> Eff e b)  -- | A handle to a stream that yields values of type @a@.  It is -- implemented as a handle to a coroutine that expects values of type@@ -237,7 +238,6 @@ -- 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.@@ -356,10 +356,10 @@ -- Left 42 -- @ try ::-  forall e (es :: Effects) a.-  (forall ex. Exception e ex -> Eff (ex :& es) a) ->+  forall exn (es :: Effects) a.+  (forall e. Exception exn e -> Eff (e :& es) a) ->   -- | @Left@ if the exception was thrown, @Right@ otherwise-  Eff es (Either e a)+  Eff es (Either exn a) try f =   UnsafeMkEff $ withScopedException_ (\throw_ -> unsafeUnEff (f (UnsafeMkException throw_))) @@ -372,10 +372,10 @@ -- "42" -- @ handle ::-  forall e (es :: Effects) a.+  forall exn (es :: Effects) a.   -- | If the exception is thrown, apply this handler-  (e -> Eff es a) ->-  (forall ex. Exception e ex -> Eff (ex :& es) a) ->+  (exn -> Eff es a) ->+  (forall e. Exception exn e -> Eff (e :& es) a) ->   Eff es a handle h f =   try f >>= \case@@ -383,10 +383,10 @@     Right a -> pure a  catch ::-  forall e (es :: Effects) a.-  (forall ex. Exception e ex -> Eff (ex :& es) a) ->+  forall exn (es :: Effects) a.+  (forall e. Exception exn e -> Eff (e :& es) a) ->   -- | If the exception is thrown, apply this handler-  (e -> Eff es a) ->+  (exn -> Eff es a) ->   Eff es a catch f h = handle h f @@ -395,13 +395,38 @@ -- exception.  This is essentially the same as -- @Control.Exception.'Control.Exception.bracket'@, whose -- documentation you can inspect for further details.+--+-- @bracket@ has a very general type that does not require @es@ to+-- contain an exception or IO effect. The reason that this is safe is:+--+--    * While @bracket@ does catch exceptions, this is unobservable,+--      since the exception is re-thrown; the cleanup action happens+--      unconditionally; and no part of it gets access to the thrown+--      exception.+--+--    * 'Eff' itself is able to guarantee that any exceptions thrown+--      in the body will be actually thrown before @bracket@+--      exits. This is inherited from the fact that @Eff@ is a wrapper+--      around 'IO'.+--+-- While it is usually the case that the cleanup action will in fact+-- want to use @IO@ effects, this is not universally true, see the+-- @polymorphicBracket@ example for an example. bracket ::+  -- | Acquire the resource   Eff es a ->+  -- | Release the resource   (a -> Eff es ()) ->+  -- | Run the body   (a -> Eff es b) ->+  -- |   Eff es b-bracket before after body = UnsafeMkEff $ Control.Exception.bracket-  (unsafeUnEff before) (unsafeUnEff . after) (unsafeUnEff . body)+bracket before after body =+  UnsafeMkEff $+    Control.Exception.bracket+      (unsafeUnEff before)+      (unsafeUnEff . after)+      (unsafeUnEff . body)  -- | -- @@@ -411,8 +436,8 @@ -- (20,10) -- @ get ::-  (st :> es) =>-  State s st ->+  (e :> es) =>+  State s e ->   -- | The current value of the state   Eff es s get (UnsafeMkState r) = UnsafeMkEff (readIORef r)@@ -425,8 +450,8 @@ -- ((), 30) -- @ put ::-  (st :> es) =>-  State s st ->+  (e :> es) =>+  State s e ->   -- | The new value of the state.  The new value is forced before   -- writing it to the state.   s ->@@ -440,8 +465,8 @@ -- ((), 20) -- @ modify ::-  (st :> es) =>-  State s st ->+  (e :> es) =>+  State s e ->   -- | Apply this function to the state.  The new value of the state   -- is forced before writing it to the state.   (s -> s) ->@@ -523,7 +548,7 @@   -- | Initial state   s ->   -- | Stateful computation-  (forall st. State s st -> Eff (st :& es) a) ->+  (forall e. State s e -> Eff (e :& es) a) ->   -- | Result and final state   Eff es (a, s) runState s f = do@@ -644,7 +669,7 @@ -- "Returned early with 5" -- @ withEarlyReturn ::-  (forall er. EarlyReturn r er -> Eff (er :& es) r) ->+  (forall e. EarlyReturn r e -> Eff (e :& es) r) ->   -- | ͘   Eff es r withEarlyReturn = handle pure@@ -659,8 +684,8 @@ -- "Returned early with 5" -- @ returnEarly ::-  (er :> es) =>-  EarlyReturn r er ->+  (e :> es) =>+  EarlyReturn r e ->   -- | Return early to the handler, with this value.   r ->   Eff es a@@ -677,7 +702,7 @@   -- | Initial state   s ->   -- | Stateful computation-  (forall st. State s st -> Eff (st :& es) a) ->+  (forall e. State s e -> Eff (e :& es) a) ->   -- | Result   Eff es a evalState s f = fmap fst (runState s f)@@ -779,7 +804,7 @@  -- | -- @--- >>> runPureEff $ withYieldToList $ \y -> do+-- >>> runPureEff $ withYieldToList $ \\y -> do --   yield y 1 --   yield y 2 --   yield y 100@@ -868,7 +893,7 @@ -- 15 -- @ withJump ::-  (forall j. Jump j -> Eff (j :& es) ()) ->+  (forall e. Jump e -> Eff (e :& es) ()) ->   -- | ͘   Eff es () withJump = withEarlyReturn@@ -889,13 +914,13 @@ -- 15 -- @ jumpTo ::-  (j :> es) =>-  Jump j ->+  (e :> es) =>+  Jump e ->   -- | ͘   Eff es a jumpTo tag = throw tag () -unwrap :: (j :> es) => Jump j -> Maybe a -> Eff es a+unwrap :: (e :> es) => Jump e -> Maybe a -> Eff es a unwrap j = \case   Nothing -> jumpTo j   Just a -> pure a
src/Bluefin/Internal/Examples.hs view
@@ -616,3 +616,33 @@           applicationState = mapHandle a,           logger = mapHandle l         }++-- This example shows a case where we can use @bracket@ polymorphically+-- in order to perform correct cleanup if @es@ is instantiated to a+-- set of effects that includes exceptions.+polymorphicBracket ::+  (st :> es) =>+  State (Integer, Bool) st ->+  Eff es () ->+  Eff es ()+polymorphicBracket st act =+  bracket+    (pure ())+    -- Always set the boolean indicating that we have terminated+    (\_ -> modify st (\(c, b) -> (c, True)))+    -- Perform the given effectful action, then increment the counter+    (\_ -> do act; modify st (\(c, b) -> ((c + 1), b)))++-- Results in (1, True)+polymorphicBracketExample1 :: (Integer, Bool)+polymorphicBracketExample1 =+  runPureEff $ do+    (_res, st) <- runState (0, False) $ \st -> polymorphicBracket st (pure ())+    pure st++-- Results in (0, True)+polymorphicBracketExample2 :: (Integer, Bool)+polymorphicBracketExample2 =+  runPureEff $ do+    (_res, st) <- runState (0, False) $ \st -> try $ \e -> polymorphicBracket st (throw e 42)+    pure st