# Pattern Matching

Branching logic written as a chain of `if`/`else` or a `switch` statement is easy
to get wrong: a forgotten case silently falls through, and adding a new variant
to a union does not force you to update every place that inspects it. The
`Match` module turns branching into a small, ordered table of cases that is
checked by the compiler. As you add cases, TypeScript tracks which inputs are
still unmatched, so finishing a matcher with `Match.exhaustive` is only allowed
once every case has been handled. Add a new union member later and the matcher
stops compiling until you handle it.

`Match` is a plain, synchronous module — it does not run inside `Effect`. Reach
for it whenever you need to classify a value: dispatching on a discriminated
union, mapping a domain event to a message, or narrowing an `unknown` input.

```ts
import { Match } from "effect"

// A discriminated union: each member carries a "_tag" field
type Event =
  | { readonly _tag: "UserCreated"; readonly id: string }
  | { readonly _tag: "UserDeleted"; readonly id: string }

// Build a reusable matcher for Event values
const describe = Match.type<Event>().pipe(
  // One branch per tag
  Match.tag("UserCreated", (event) => `created ${event.id}`),
  Match.tag("UserDeleted", (event) => `deleted ${event.id}`),
  // Compiles only because every tag above is handled
  Match.exhaustive
)

console.log(describe({ _tag: "UserCreated", id: "u1" }))
// Output: "created u1"
```

## How it works

A matcher is built in three stages:

1. **Start** a matcher with [`Match.type<T>()`](https://effect.plants.sh/pattern-matching/match/#match-by-type)
   for a reusable function over a known type, or
   [`Match.value(x)`](https://effect.plants.sh/pattern-matching/match/#match-by-value) to classify one
   value immediately.
2. **Add cases** with combinators like `Match.when`, `Match.tag`, and
   `Match.not`. Cases are tested top to bottom, and the first one that matches
   wins.
3. **Finish** with `Match.exhaustive` (require every case to be covered),
   `Match.orElse` (supply a fallback), or `Match.option` / `Match.result`
   (return the outcome as an [`Option`](https://effect.plants.sh/data-types/option/) or
   [`Result`](https://effect.plants.sh/data-types/result/) instead of throwing on a miss).

## In this section

- **[Building matchers](https://effect.plants.sh/pattern-matching/match/)** — the full toolkit:
  `Match.type` vs `Match.value`, predicates and object patterns with
  `Match.when`, tag- and discriminator-based matching, and the finalizers that
  turn a matcher into a value or a function.