Skip to content

The Effect Type

The Effect type is an immutable description of a workflow or operation that is lazily executed. This means that when you create an Effect, it doesn’t run immediately, but instead defines a program that can succeed, fail, or require some additional context to complete.

Here is the general form of an Effect:

┌─── Represents the success type
│ ┌─── Represents the error type
│ │ ┌─── Represents required dependencies
▼ ▼ ▼
Effect<Success, Error, Requirements>

This type indicates that an effect:

  • Succeeds and returns a value of type Success
  • Fails with an error of type Error
  • May need certain contextual dependencies of type Requirements to execute

Conceptually, you can think of Effect as an effectful version of the following function type:

type Effect<Success, Error, Requirements> = (
context: Context<Requirements>
) => Error | Success

However, effects are not actually functions. They can model synchronous, asynchronous, concurrent, and resourceful computations.

Immutability. Effect values are immutable, and every function in the Effect library produces a new Effect value.

Modeling Interactions. These values do not perform any actions themselves, they simply model or describe effectful interactions.

Execution. An Effect can be executed by the Effect Runtime System, which interprets it into actual interactions with the external world. Ideally, this execution happens at a single entry point in your application, such as the main function where effectful operations are initiated.

The Effect type has three type parameters with the following meanings:

ParameterDescription
SuccessRepresents the type of value that an effect can succeed with when executed. If this type parameter is void, it means the effect produces no useful information, while if it is never, it means the effect runs forever (or until failure).
ErrorRepresents the expected errors that can occur when executing an effect. If this type parameter is never, it means the effect cannot fail, because there are no values of type never.
RequirementsRepresents the contextual data required by the effect to be executed. This data is stored in a collection named Context. If this type parameter is never, it means the effect has no requirements and the Context collection is empty.

By using the utility types Effect.Success, Effect.Error, and Effect.Context, you can extract the corresponding types from an effect.

Example (Extracting Success, Error, and Context Types)

import {
import Effect

@since2.0.0

@since2.0.0

@since2.0.0

Effect
,
import Context

@since2.0.0

@since2.0.0

Context
} from "effect"
class
class SomeContext
SomeContext
extends
import Context

@since2.0.0

@since2.0.0

Context
.
const Tag: <"SomeContext">(id: "SomeContext") => <Self, Shape>() => Context.TagClass<Self, "SomeContext", Shape>

@example

import { Context, Layer } from "effect"
class MyTag extends Context.Tag("MyTag")<
MyTag,
{ readonly myNum: number }
>() {
static Live = Layer.succeed(this, { myNum: 108 })
}

@since2.0.0

Tag
("SomeContext")<
class SomeContext
SomeContext
, {}>() {}
// Assume we have an effect that succeeds with a number,
// fails with an Error, and requires SomeContext
declare const
const program: Effect.Effect<number, Error, SomeContext>
program
:
import Effect

@since2.0.0

@since2.0.0

@since2.0.0

Effect
.
interface Effect<out A, out E = never, out R = never>

The Effect interface defines a value that describes a workflow or job, which can succeed or fail.

Details

The Effect interface represents a computation that can model a workflow involving various types of operations, such as synchronous, asynchronous, concurrent, and parallel interactions. It operates within a context of type R, and the result can either be a success with a value of type A or a failure with an error of type E. The Effect is designed to handle complex interactions with external resources, offering advanced features such as fiber-based concurrency, scheduling, interruption handling, and scalability. This makes it suitable for tasks that require fine-grained control over concurrency and error management.

To execute an Effect value, you need a Runtime, which provides the environment necessary to run and manage the computation.

@since2.0.0

@since2.0.0

Effect
<number,
interface Error
Error
,
class SomeContext
SomeContext
>
// Extract the success type, which is number
type
type A = number
A
=
import Effect

@since2.0.0

@since2.0.0

@since2.0.0

Effect
.
namespace Effect

The Effect interface defines a value that describes a workflow or job, which can succeed or fail.

Details

The Effect interface represents a computation that can model a workflow involving various types of operations, such as synchronous, asynchronous, concurrent, and parallel interactions. It operates within a context of type R, and the result can either be a success with a value of type A or a failure with an error of type E. The Effect is designed to handle complex interactions with external resources, offering advanced features such as fiber-based concurrency, scheduling, interruption handling, and scalability. This makes it suitable for tasks that require fine-grained control over concurrency and error management.

To execute an Effect value, you need a Runtime, which provides the environment necessary to run and manage the computation.

@since2.0.0

@since2.0.0

Effect
.
type Effect<out A, out E = never, out R = never>.Success<T extends Effect.Effect<any, any, any>> = [T] extends [Effect.Effect<infer _A, infer _E, infer _R>] ? _A : never

@since2.0.0

Success
<typeof
const program: Effect.Effect<number, Error, SomeContext>
program
>
// Extract the error type, which is Error
type
type E = Error
E
=
import Effect

@since2.0.0

@since2.0.0

@since2.0.0

Effect
.
namespace Effect

The Effect interface defines a value that describes a workflow or job, which can succeed or fail.

Details

The Effect interface represents a computation that can model a workflow involving various types of operations, such as synchronous, asynchronous, concurrent, and parallel interactions. It operates within a context of type R, and the result can either be a success with a value of type A or a failure with an error of type E. The Effect is designed to handle complex interactions with external resources, offering advanced features such as fiber-based concurrency, scheduling, interruption handling, and scalability. This makes it suitable for tasks that require fine-grained control over concurrency and error management.

To execute an Effect value, you need a Runtime, which provides the environment necessary to run and manage the computation.

@since2.0.0

@since2.0.0

Effect
.
type Effect<out A, out E = never, out R = never>.Error<T extends Effect.Effect<any, any, any>> = [T] extends [Effect.Effect<infer _A, infer _E, infer _R>] ? _E : never

@since2.0.0

Error
<typeof
const program: Effect.Effect<number, Error, SomeContext>
program
>
// Extract the context type, which is SomeContext
type
type R = SomeContext
R
=
import Effect

@since2.0.0

@since2.0.0

@since2.0.0

Effect
.
namespace Effect

The Effect interface defines a value that describes a workflow or job, which can succeed or fail.

Details

The Effect interface represents a computation that can model a workflow involving various types of operations, such as synchronous, asynchronous, concurrent, and parallel interactions. It operates within a context of type R, and the result can either be a success with a value of type A or a failure with an error of type E. The Effect is designed to handle complex interactions with external resources, offering advanced features such as fiber-based concurrency, scheduling, interruption handling, and scalability. This makes it suitable for tasks that require fine-grained control over concurrency and error management.

To execute an Effect value, you need a Runtime, which provides the environment necessary to run and manage the computation.

@since2.0.0

@since2.0.0

Effect
.
type Effect<out A, out E = never, out R = never>.Context<T extends Effect.Effect<any, any, any>> = [T] extends [Effect.Effect<infer _A, infer _E, infer _R>] ? _R : never

@since2.0.0

Context
<typeof
const program: Effect.Effect<number, Error, SomeContext>
program
>