Effect.ts: Absence as First-Class

Data TypesLesson 35 of 51

35. Pattern Matching - Exhaustive Absence Handling

Match on different absence types - compiler ensures you handle all cases

Code Example
import { Match } from "effect";

type Result =
  | { _tag: "Success"; value: number }
  | { _tag: "Loading" }
  | { _tag: "Error"; message: string };

const result: Result = { _tag: "Loading" };

const message = Match.value(result).pipe(
  Match.tag("Success", ({ value }) =>
    `Got value: ${value}`
  ),
  Match.tag("Loading", () =>
    "Still waiting..."  // Absence being resolved
  ),
  Match.tag("Error", ({ message }) =>
    `Failed: ${message}`  // Absence failed to resolve
  ),
  Match.exhaustive  // Compiler enforces all cases!
);

// Forgot a case? Type error!
Interactive Example
const { Match } = await import('effect');
const result = { _tag: 'Success', value: 42 };
const message = Match.value(result).pipe(
      Match.tag('Success', ({ value }) => 'Got: ' + value),
      Match.tag('Loading', () => 'Waiting...'),
      Match.tag('Error', ({ message }) => 'Failed: ' + message),
      Match.exhaustive
);
return `Pattern matching!Result type: SuccessMatched: ${message}Exhaustive (all cases handled)!`;
Explanation

Pattern matching: exhaustive absence handling.

Traditional approach: if/else chains, forget cases, bugs. Match types exhaustive absence patterns:

  • Success: absence was resolved
  • Loading: absence is being resolved
  • Error: absence failed to resolve
  • Compiler: "did you handle ALL absence patterns?"

No assumptions about which case occurs - handle them all or type error!

Absence-first safety: can't forget to handle absence patterns!


Part 35 of 51 in the Effect.ts Absence Modeling series