effectful-core 2.2.0.0 → 2.2.1.0
raw patch · 5 files changed
+76/−25 lines, 5 filesPVP ok
version bump matches the API change (PVP)
API changes (from Hackage documentation)
+ Effectful.Dispatch.Dynamic: localLift :: (HasCallStack, SharedSuffix es handlerEs) => LocalEnv localEs handlerEs -> UnliftStrategy -> ((forall r. Eff es r -> Eff localEs r) -> Eff es a) -> Eff es a
+ Effectful.Dispatch.Dynamic: localSeqLift :: (HasCallStack, SharedSuffix es handlerEs) => LocalEnv localEs handlerEs -> ((forall r. Eff es r -> Eff localEs r) -> Eff es a) -> Eff es a
Files
- CHANGELOG.md +3/−0
- README.md +29/−21
- effectful-core.cabal +1/−1
- src/Effectful/Dispatch/Dynamic.hs +43/−0
- src/Effectful/Internal/Unlift.hs +0/−3
CHANGELOG.md view
@@ -1,3 +1,6 @@+# effectful-core-2.2.1.0 (2022-11-09)+* Add `localSeqLift` and `localLift` to `Effectful.Dispatch.Dynamic`.+ # effectful-core-2.2.0.0 (2022-10-24) * Change `PrimState` for `Eff` from `RealWorld` to `PrimStateEff` to prevent the `Prim` effect from executing arbitrary `IO` actions via `ioToPrim`.
README.md view
@@ -40,10 +40,11 @@ [polysemy](https://hackage.haskell.org/package/polysemy), [eff](https://github.com/hasura/eff) and probably a few more. -Unfortunately, of all of them only `eff` is a promising proposition because of-reasonable performance characteristics (see the talk [Effects for-Less](https://www.youtube.com/watch?v=0jI-AlWEwYI) for more information) and-potential for good interoperability with the existing ecosystem.+It needs to be noted that of all of them only the work-in-progress `eff` library+is a promising proposition because of reasonable performance characteristics+(see the talk [Effects for Less](https://www.youtube.com/watch?v=0jI-AlWEwYI)+for more information) and potential for good interoperability with the existing+ecosystem. The second point is arguably the most important, because it allows focusing on things that matter instead of reinventing all kinds of wheels, hence being a@@ -88,8 +89,8 @@ What is more, the `Eff` monad is concrete, so GHC has many possibilities for optimization, which results in a very fast code at a default optimization-level. There is no need to mark every function `INLINE` or enable additional-optimization passes, it just works.+level. There is no need to explicitly mark functions with `INLINE` pragmas or+enable additional optimization passes, it just works. ### Any downsides? @@ -117,36 +118,43 @@ ### Summary -`effectful` is an extensible effects library that aims to replace "boring"-transformer stacks (which consist of a dozen of newtype'd `ExceptT`, `ReaderT`,-`StateT` and `WriterT` transformers) and their derivatives by providing-equivalent effects with improved semantics, performance and usability (it also-makes it easy to reuse them for your own effects). It doesn't try to make monad-transformers obsolete, so you're free to use it with `ConduitT`, `ContT`,-`ListT` etc. when necessary.+`effectful` is an extensible effects library that aims to be the replacement+for: +- The bare `ReaderT` pattern by being essentially its enriched version.++- Monad transformer stacks typically encountered in the wild (i.e. consisting of+ a dozen of newtype'd `ExceptT`, `ReaderT`, `StateT` and `WriterT` transformers+ and their derivatives) by providing equivalent effects with improved+ semantics, performance, usability and making it easy to reuse them for your+ own effects.++It doesn't try to make monad transformers obsolete, so you're free to+use it with `ConduitT`, `ContT`, `ListT` etc. when necessary.+ ## Package structure -The effect system is split among several libraries:+The library is split among several packages: - The [`effectful-core`](https://hackage.haskell.org/package/effectful-core)- library contains the core of the effect system along with the basic- effects. It aims for a small dependency footprint and provides building blocks- for more advanced effects.+ package contains the core of the library along with basic effects. It aims for+ a small dependency footprint and provides building blocks for more advanced+ effects. - The [`effectful-plugin`](https://hackage.haskell.org/package/effectful-plugin)- library provides an optional GHC plugin for improving disambiguation of+ package provides an optional GHC plugin for improving disambiguation of effects (see [here](https://github.com/haskell-effectful/effectful/blob/master/effectful-plugin/README.md) for more information). -- The [`effectful-th`](https://hackage.haskell.org/package/effectful-th) library+- The [`effectful-th`](https://hackage.haskell.org/package/effectful-th) package provides utilities for generating bits of effect-related boilerplate via Template Haskell. -- The [`effectful`](https://hackage.haskell.org/package/effectful) library+- The [`effectful`](https://hackage.haskell.org/package/effectful) package re-exports public modules of `effectful-core` and additionally provides most- features of the `unliftio` library divided into appropriate effects.+ features of the [`unliftio`](https://hackage.haskell.org/package/unliftio)+ package divided into appropriate effects. ## Example
effectful-core.cabal view
@@ -1,7 +1,7 @@ cabal-version: 2.4 build-type: Simple name: effectful-core-version: 2.2.0.0+version: 2.2.1.0 license: BSD-3-Clause license-file: LICENSE category: Control
src/Effectful/Dispatch/Dynamic.hs view
@@ -33,6 +33,8 @@ , localUnliftIO -- *** Lifts+ , localSeqLift+ , localLift , withLiftMap , withLiftMapIO @@ -508,6 +510,47 @@ localUnliftIO (LocalEnv les) strategy k = case strategy of SeqUnlift -> liftIO $ seqUnliftIO les k ConcUnlift p l -> liftIO $ concUnliftIO les p l k++----------------------------------------+-- Lifts++-- | Create a local lifting function with the 'SeqUnlift' strategy. For the+-- general version see 'localLift'.+--+-- @since 2.2.1.0+localSeqLift+ :: (HasCallStack, SharedSuffix es handlerEs)+ => LocalEnv localEs handlerEs+ -- ^ Local environment.+ -> ((forall r. Eff es r -> Eff localEs r) -> Eff es a)+ -- ^ Continuation with the lifting function in scope.+ -> Eff es a+localSeqLift !_ k = unsafeEff $ \es -> do+ -- The LocalEnv parameter is not used, but we need it to constraint the+ -- localEs type variable. It's also strict so that callers don't cheat.+ seqUnliftIO es $ \unlift -> do+ (`unEff` es) $ k $ unsafeEff_ . unlift++-- | Create a local lifting function with the given strategy.+--+-- @since 2.2.1.0+localLift+ :: (HasCallStack, SharedSuffix es handlerEs)+ => LocalEnv localEs handlerEs+ -- ^ Local environment.+ -> UnliftStrategy+ -> ((forall r. Eff es r -> Eff localEs r) -> Eff es a)+ -- ^ Continuation with the lifting function in scope.+ -> Eff es a+localLift !_ strategy k = case strategy of+ -- The LocalEnv parameter is not used, but we need it to constraint the+ -- localEs type variable. It's also strict so that callers don't cheat.+ SeqUnlift -> unsafeEff $ \es -> do+ seqUnliftIO es $ \unlift -> do+ (`unEff` es) $ k $ unsafeEff_ . unlift+ ConcUnlift p l -> unsafeEff $ \es -> do+ concUnliftIO es p l $ \unlift -> do+ (`unEff` es) $ k $ unsafeEff_ . unlift -- | Utility for lifting 'Eff' computations of type --
src/Effectful/Internal/Unlift.hs view
@@ -38,9 +38,6 @@ -- | The strategy to use when unlifting 'Effectful.Eff' computations via -- 'Effectful.withEffToIO', 'Effectful.withRunInIO' or the -- 'Effectful.Dispatch.Dynamic.localUnlift' family.------ /Note:/ unlifting functions should not be used outside of continuations that--- brought them into scope. data UnliftStrategy = SeqUnlift -- ^ The fastest strategy and a default setting for t'Effectful.IOE'. An