Skip to content

Latest commit

 

History

History
80 lines (63 loc) · 1.96 KB

File metadata and controls

80 lines (63 loc) · 1.96 KB
title Avoid Long Chains of .andThen; Use Generators Instead
id avoid-long-andthen-chains
skillLevel intermediate
applicationPatternId domain-modeling
summary Prefer Effect.gen over long chains of .andThen for sequential logic to improve readability and maintainability.
tags
andThen
generators
readability
composition
anti-pattern
rule
description
Prefer generators over long chains of .andThen.
related
use-gen-for-business-logic
author Dillon Mulroy
lessonOrder 2

Avoid Long Chains of .andThen; Use Generators Instead

Guideline

For sequential logic involving more than two steps, prefer Effect.gen over chaining multiple .andThen or .flatMap calls.

Rationale

Effect.gen provides a flat, linear code structure that is easier to read and debug than deeply nested functional chains.

Good Example

import { Effect } from "effect";

// Define our steps with logging
const step1 = (): Effect.Effect<number> =>
  Effect.succeed(42).pipe(Effect.tap((n) => Effect.log(`Step 1: ${n}`)));

const step2 = (a: number): Effect.Effect<string> =>
  Effect.succeed(`Result: ${a * 2}`).pipe(
    Effect.tap((s) => Effect.log(`Step 2: ${s}`))
  );

// Using Effect.gen for better readability
const program = Effect.gen(function* () {
  const a = yield* step1();
  const b = yield* step2(a);
  return b;
});

// Run the program
const programWithLogging = Effect.gen(function* () {
  const result = yield* program;
  yield* Effect.log(`Final result: ${result}`);
  return result;
});

Effect.runPromise(programWithLogging);

Explanation:
Generators keep sequential logic readable and easy to maintain.

Anti-Pattern

import { Effect } from "effect";
declare const step1: () => Effect.Effect<any>;
declare const step2: (a: any) => Effect.Effect<any>;

step1().pipe(Effect.flatMap((a) => step2(a))); // Or .andThen

Chaining many .flatMap or .andThen calls leads to deeply nested, hard-to-read code.