Home

Awesome

effectful

Build Status Hackage Dependencies Stackage LTS Stackage Nightly

<img src="https://user-images.githubusercontent.com/387658/127747903-f728437f-2ee4-47b8-9f0c-5102fd44c8e4.png" width="128">

An easy to use, fast extensible effects library with seamless integration with the existing Haskell ecosystem.

Main features:

  1. Very fast (benchmarks).

  2. Easy to use API (comparable with usage of the MonadUnliftIO class).

  3. Correct semantics in presence of runtime exceptions (no more discarded state updates).

  4. Seamless integration with the existing ecosystem (exceptions, monad-control, unliftio-core, resourcet etc.).

  5. Support for thread local and shared state (e.g. StateT provides a thread local state, while MVar holds a shared state, both approaches have their merits).

  6. 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:

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:

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

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:

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:

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:

Blog posts:


<div>Icons made by <a href="https://www.freepik.com" title="Freepik">Freepik</a> from <a href="https://www.flaticon.com/" title="Flaticon">www.flaticon.com</a></div>