on master help sign in

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

git clone ssh://git.iko.soy/effectful

effectful

Build Status Documentation Documentation

Note: this is a pre-release.

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

Main features:

  1. Very fast (benchmark results with GHC 8.8.4: countdown, filesize, comparison with eff).

  2. Easy to use API (no boilerplate code and dealing with arcane types).

  3. Correct semantics in presence of runtime exceptions (no more lost state modifications).

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

  5. Effects can be defined for either

    • static dispatch (as fast as it gets, single interpretation) or

    • dynamic dispatch (a bit slower, multiple interpretations),

    depending on your needs.

Motivation

Do we really need yet another library for handling effects? There's freer-simple, fused-effects, polysemy, 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" linked below 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 and is crucial for adoption of the library.

However, eff uses delimited continuations underneath, which:

On the other hand, if support for continuations is excluded from the handler monad, then the ability to define effects with non-linear control flow (such as NonDet) is lost. Arguably it's a small price to pay for predictability, because such specialized effects are needed rarely and locally, at which point a dedicated, well established solution such as conduit, list-t or logict can be used.

This is where effectful comes in. The Eff monad it uses is essentially a ReaderT over IO on steroids, allowing us to dynamically extend its environment with data types that represent effects or their handlers.

Because this concept is so simple:

What is more:

In conclusion, effectful aims to reduce duplication and bring back performance to "boring" transformer stacks, most of which are a dozen of newtype'd StateT or ReaderT transformers, each with a few associated operations (usually tied to a type class), not to replace monad transformers altogether.

Usage

The effect system and its effects are split among several libraries:

Example

A Filesystem effect with two handlers, one that runs in IO and another that uses an in-memory virtual file system can be found here.

Resources

Resources that inspired the rise of this library and had a lot of impact on its design.

Talks:

Blog posts:


Icons made by Freepik from www.flaticon.com