The Effect System

Description of the core effect system

Effect Type & Aliases

The main type you will be working with is:

type Effect<S, R, E, A>

type Async<A> = Effect<unknown, unknown, never, A>;
type AsyncE<E, A> = Effect<unknown, unknown, E, A>;
type AsyncR<R, A> = Effect<unknown, R, never, A>;
type AsyncRE<R, E, A> = Effect<unknown, R, E, A>;

type Sync<A> = Effect<never, unknown, never, A>;
type SyncE<E, A> = Effect<never, unknown, E, A>;
type SyncR<R, A> = Effect<never, R, never, A>;
type SyncRE<R, E, A> = Effect<never, R, E, A>;

The Effect signature reads as follows:

Effect<S, R, E, A> is an effectful computation that 

can be Synchronous or Asynchronous (S) and
requires an environment of type R to run and
can produce either an error of type E or
a success reponse of type A

Package Exports

Below the lost of exported modules included in @matechs/aio

Simple Effect

Let's start with a simple synchronous computation:

The same computation can run in different ways:

Let's add some asynchronousity to the computation by adding a simple delay via liftDelay:

If we now try to use runSync we will get a compile error:

This is the first time we see a very important principle in statically typed functional programming, encoding logic at the type level to make errors impossible.

Environmental Effect

We can create a module that wraps the add / mul operations in the environment as follows:

Multiple Environments

We can arbitrarily compose computations that require different environments as follows:

Note how we purposly omitted the type of addAndMul to show that all requirements are correctly inferred from usage, in fact if we forget to provide one dependency we will get a compilation error indicating that the dependency is missing as follows

Combining Providers

We can combine arbitrary providers as follows:

Higher Order Dependencies

Sometimes you may want to have your providers depending on other modules, you can do that as follows:

Last updated

Was this helpful?