Hyperlinkv0.8.0-beta.28

Effect

Effect.flatMapconsteffect/Effect.ts:1958
<A, B, E1, R1>(f: (a: A) => Effect<B, E1, R1>): <E, R>(
  self: Effect<A, E, R>
) => Effect<B, E1 | E, R1 | R>
<A, E, R, B, E1, R1>(
  self: Effect<A, E, R>,
  f: (a: A) => Effect<B, E1, R1>
): Effect<B, E | E1, R | R1>

Chains effects to produce new Effect instances, useful for combining operations that depend on previous results.

When to use

Use when you need to chain multiple effects, ensuring that each step produces a new Effect while flattening any nested effects that may occur.

Details

flatMap lets you sequence effects so that the result of one effect can be used in the next step. It is similar to flatMap used with arrays but works specifically with Effect instances, allowing you to avoid deeply nested effect structures.

Since effects are immutable, flatMap always returns a new effect instead of changing the original one.

Example (Choosing flatMap syntax variants)

import { Effect, pipe } from "effect"

const myEffect = Effect.succeed(1)
const transformation = (n: number) => Effect.succeed(n + 1)

const flatMappedWithPipe = pipe(myEffect, Effect.flatMap(transformation))
const flatMappedWithDataFirst = Effect.flatMap(myEffect, transformation)
const flatMappedWithMethod = myEffect.pipe(Effect.flatMap(transformation))

Example (Sequencing dependent effects)

import { Data, Effect, pipe } from "effect"

class DiscountRateError extends Data.TaggedError("DiscountRateError")<{}> {}

// Function to apply a discount safely to a transaction amount
const applyDiscount = (
  total: number,
  discountRate: number
): Effect.Effect<number, DiscountRateError> =>
  discountRate === 0
    ? Effect.fail(new DiscountRateError())
    : Effect.succeed(total - (total * discountRate) / 100)

// Simulated asynchronous task to fetch a transaction amount from database
const fetchTransactionAmount = Effect.promise(() => Promise.resolve(100))

// Chaining the fetch and discount application using `flatMap`
const finalAmount = pipe(
  fetchTransactionAmount,
  Effect.flatMap((amount) => applyDiscount(amount, 5))
)

Effect.runPromise(finalAmount).then(console.log)
// Output: 95
sequencingtap
Source effect/Effect.ts:19589 lines
export const flatMap: {
  <A, B, E1, R1>(
    f: (a: A) => Effect<B, E1, R1>
  ): <E, R>(self: Effect<A, E, R>) => Effect<B, E1 | E, R1 | R>
  <A, E, R, B, E1, R1>(
    self: Effect<A, E, R>,
    f: (a: A) => Effect<B, E1, R1>
  ): Effect<B, E | E1, R | R1>
} = internal.flatMap
Referenced by 129 symbols