effectful-core
An easy to use, performant extensible effects library.
| LTS Haskell 24.17: | 2.6.1.0 | 
| Stackage Nightly 2025-10-31: | 2.6.1.0 | 
| Latest on Hackage: | 2.6.1.0 | 
effectful-core-2.6.1.0@sha256:329f7bd7319217b668ca00331b31f683af93ba18423462918217b2becec3d6f0,4359Module documentation for 2.6.1.0
- Effectful
- Effectful.Dispatch
- Effectful.Error
- Effectful.Exception
- Effectful.Fail
- Effectful.Internal
- Effectful.Labeled
- Effectful.NonDet
- Effectful.Prim
- Effectful.Provider
- Effectful.Reader
- Effectful.State- Effectful.State.Dynamic
- Effectful.State.Static
 
- Effectful.Writer- Effectful.Writer.Dynamic
- Effectful.Writer.Static
 
 
effectful
An easy to use, fast extensible effects library with seamless integration with the existing Haskell ecosystem.
Main features:
- 
Very fast (benchmarks). 
- 
Easy to use API (comparable with usage of the MonadUnliftIO class). 
- 
Correct semantics in presence of runtime exceptions (no more discarded state updates). 
- 
Seamless integration with the existing ecosystem ( exceptions,monad-control,unliftio-core,resourcetetc.).
- 
Support for thread local and shared state (e.g. StateTprovides a thread local state, whileMVarholds a shared state, both approaches have their merits).
- 
Support for statically (implementation determined at compile time) and dynamically (implementation determined at run time) dispatched effects. 
Motivation
Do we really need yet another library for handling effects? There’s freer-simple, fused-effects, polysemy, eff and probably a few more.
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
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 necessary condition for broader adoption of the library.
Unfortunately, the development of eff has stalled due to a
few
subtle
issues related to its use of
delimited continuations underneath.
What about mtl?
It’s true that its “effects as classes” approach is widely known and used often.
However:
- 
mtlstyle effects are slow.
- 
The majority of popular monad transformers (except ReaderT) used for effect implementations are rife with subtle issues.
These are problematic enough that the ReaderT design pattern was invented. Its fundamentals are solid, but it’s not an effect system.
A solution? Use the ReaderT pattern as a base and build around it to make an
extensible effects library! This is where effectful comes in. The Eff monad
it uses is essentially a ReaderT over IO on steroids, allowing us to extend
its environment with data types representing effects.
This concept is quite simple, so:
- 
It’s reasonably easy to understand what is going on under the hood. 
- 
The Effmonad being a reader allows for seamless interoperability with ubiquitous classes such asMonadBaseControlandMonadUnliftIOand solves issues of monad transformers mentioned above.
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 explicitly mark functions with INLINE pragmas or
enable additional optimization passes, it just works.
Any downsides?
As always, there’s no free lunch. The Eff monad doesn’t support effect
handlers that require the ability to suspend or capture the rest of the
computation and resume it later (potentially multiple times). This prevents
effectful from providing (in particular):
- 
A NonDeteffect handler that executes multipleAlternativebranches and collects their results.
- 
A Coroutineeffect.
It needs to be noted however that such NonDet effect handler in existing
libraries is
broken
and none of the ones with support for higher order effects provide the
Coroutine effect, so arguably it’s not a big loss.
If you need such capability in your application, there are well established
libraries such as conduit or
list-t that can be used with
effectful without any hassle.
Summary
effectful is an extensible effects library that aims to be the replacement
for:
- 
The bare ReaderTpattern 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,StateTandWriterTtransformers 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 library is split among several packages:
- 
The effectful-corepackage 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-pluginpackage provides an optional GHC plugin for improving disambiguation of effects (see here for more information).
- 
The effectful-thpackage provides utilities for generating bits of effect-related boilerplate via Template Haskell.
- 
The effectfulpackage re-exports public modules ofeffectful-coreand additionally provides most features of theunliftiopackage divided into appropriate effects.
Examples
For the examples see the Introduction sections of
Effectful.Dispatch.Dynamic
and
Effectful.Dispatch.Static
(when in doubt, start with dynamic dispatch).
Acknowledgements
To all contributors of existing effect libraries - thank you for putting the
time and effort to explore the space. In particular, conversations in issue
trackers of cleff, eff, freer-simple, fused-effects and polysemy
repositories were invaluable in helping me discover and understand challenges in
the space.
Resources
Resources that inspired the rise of this library and had a lot of impact on its design.
Talks:
- 
Effects for Less by Alexis King. 
- 
Monad Transformer State by Michael Snoyman. 
Blog posts:
- 
ReaderT design pattern by Michael Snoyman. 
- 
Exceptions Best Practices by Michael Snoyman. 
Changes
effectful-core-2.6.1.0 (2025-08-30)
- Add MonadError,MonadReader,MonadStateandMonadWriterinstances forEfffor compatibility with existing code.
effectful-core-2.6.0.0 (2025-06-13)
- Adjust generalBracketwithbase >= 4.21to make use of the new exception annotation mechanism.
- Add withExceptiontoEffectful.Exception.
- Deprecate Effectful.Reader.Dynamic.withReaderas it doesn’t work correctly for all potential interpreters.
- Breaking changes:
- Change the order of type parameters in raisefor better usability.
- Effectful.Error.Static.ErrorWrapperis no longer caught by- catchSync.
- Remove deprecated function Effectful.withConcEffToIO.
 
- Change the order of type parameters in 
effectful-core-2.5.1.0 (2024-11-27)
- Add passthroughtoEffectful.Dispatch.Dynamicfor passing operations to the upstream handler withininterposeandimposewithout having to fully pattern match on them.
- Bugfixes:
- Fix a potential space leak related to HasCallStackquirks (see https://gitlab.haskell.org/ghc/ghc/-/issues/25520 for more information).
 
- Fix a potential space leak related to 
effectful-core-2.5.0.0 (2024-10-23)
- Add plusEff(specialized version of<|>) toEffectful.NonDetand makeemptyEffandsumEffgenerate better call stacks.
- Explicitly define setByteArray#andsetOffAddr#in thePriminstance ofRefforprimitive< 0.9.0.0.
- Bugfixes:
- OnEmptyRollbackstrategy of the- NonDeteffect is no longer broken.
 
- Breaking changes:
- Remove restoreEnvfunction fromEffectful.Dispatch.Static.Primitivesince it was broken.
- Base Effectful.ExceptiononControl.Exceptioninstead of thesafe-exceptionslibrary for consistency with providedMonadThrowandMonadCatchinstances.
 
- Remove 
effectful-core-2.4.0.0 (2024-10-08)
- Add utility functions for handling effects that take the effect handler as the
last parameter to Effectful.Dispatch.Dynamic.
- Add utility functions for handling first order effects to
Effectful.Dispatch.Dynamic.
- Improve Effectful.Labeled, addEffectful.Labeled.Error,Effectful.Labeled.Reader,Effectful.Labeled.StateandEffectful.Labeled.Writer.
- Add throwErrorWithandthrowError_toEffectful.Error.StaticandEffectful.Error.Dynamic.
- Add HasCallStackconstraints where appropriate for better debugging experience.
- Add a SeqForkUnliftstrategy to support running unlifting functions outside of the scope of effects they capture.
- Add Effectful.Exceptionwith appropriate re-exports from thesafe-exceptionslibrary.
- Bugfixes:
- Ensure that a LocalEnvis only used in a thread it belongs to.
- Properly roll back changes made to the environment when OnEmptyRollbackpolicy for theNonDeteffect is selected.
- Fix a bug in stateMandmodifyMof thread localStateeffect that might’ve caused dropped state updates (#237).
 
- Ensure that a 
- Breaking changes:
- localSeqLend,- localLend,- localSeqBorrowand- localBorrownow take a list of effects instead of a single one.
- Effectful.Error.Static.throwErrornow requires the error type to have a- Showconstraint. If this is not the case for some of your error types, use- throwError_for them.
- ThrowErroroperation from the dynamic version of the- Erroreffect was replaced with- ThrowErrorWith.
- stateEnvand- modifyEnvnow take pure modification functions. If you rely on their old forms, switch to a combination of- getEnvand- putEnv.
- runStateMVar,- evalStateMVarand- execStateMVarnow take a strict- MVar'from the- strict-mutable-basepackage.
 
effectful-core-2.3.1.0 (2024-06-07)
- Drop support for GHC 8.8.
- Remove inaccurate information from the Showinstance ofErrorWrapper.
- Add Effectful.Provider.List, generalization ofEffectful.Provider.
- Respect withFrozenCallStackused by callers ofsend.
- Support exchange of effects between the environment of the handler and the
local one via localSeqLend,localLend,localSeqBorrowandlocalBorrowfromEffectful.Dispatch.Dynamic.
effectful-core-2.3.0.1 (2023-11-13)
- Prevent internal functions from appending call stack frames to handlers.
effectful-core-2.3.0.0 (2023-09-13)
- Deprecate withConcEffToIO.
- Make withEffToIOtake an explicit unlifting strategy for the sake of consistency with unlifting functions fromEffectful.Dispatch.Dynamicand easier to understand API.
- Add support for turning an effect handler into an effectful operation via the
Providereffect.
- Add runErrorWithandrunErrorNoCallStackWithtoEffectful.Error.DynamicandEffectful.Error.Static.
- Add support for having multiple effects of the same type in scope via the
Labeledeffect.
effectful-core-2.2.2.2 (2023-03-13)
- Allow injectto turn a monomorphic effect stack into a polymorphic one.
- Use C sources only with GHC < 9.
- Force inlining of bracketearly to work around excessive inlining problem with GHC 9.6 (https://gitlab.haskell.org/ghc/ghc/-/issues/22824).
effectful-core-2.2.2.1 (2023-01-12)
- Stop using the internal library because of bugs in stack.
effectful-core-2.2.2.0 (2023-01-11)
- Add withSeqEffToIOandwithConcEffToIOtoEffectful.
- Use strict IORefandMVarvariants where appropriate.
- Make injectwork with effect stacks sharing a polymorphic suffix.
effectful-core-2.2.1.0 (2022-11-09)
- Add localSeqLiftandlocalLifttoEffectful.Dispatch.Dynamic.
effectful-core-2.2.0.0 (2022-10-24)
- Change PrimStateforEfffromRealWorldtoPrimStateEffto prevent thePrimeffect from executing arbitraryIOactions viaioToPrim.
- Deprecate (:>>)as GHC can’t efficiently deal with type families.
- Add support for the AlternativeandMonadPlusinstances forEffvia theNonDeteffect.
effectful-core-2.1.0.0 (2022-08-22)
- Include the e :> localEsconstraint in theEffectHandlerto allow more flexibility in handling higher order effects.
- Do not include internal stack frames in throwErrorfromEffectful.Error.Dynamic.
effectful-core-2.0.0.0 (2022-08-12)
- Make storage references in the environment immutable.
- Remove checkSizeEnvandforkEnvfromEffectful.Dispatch.Static.Primitive.
- Add internal versioning of effects to prevent leakage of unsafeCoerce.
- Make interposeandimposeproperly interact with other handlers.
effectful-core-1.2.0.0 (2022-07-28)
- Change SuffixOftoSharedSuffixand make it behave as advertised.
- Add raiseWith.
effectful-core-1.1.0.0 (2022-07-19)
- Don’t reset the UnliftStrategytoSeqUnliftinside the continuation ofwithEffToIO.
- Add withReader.
effectful-core-1.0.0.0 (2022-07-13)
- Initial release.
