jonnifyelixir
F2 / F2.07 / matching

F2.07 · part 3 of 3

Pattern matching on data

Pattern matching is how algebraic data is taken apart. A pattern mirrors the shape of a value: match it and the names inside bind to the matching pieces. For a sum, a clause per variant dispatches on the tag; for a product, the pattern reaches in and pulls out fields.

It is the same matching seen in F1.08, now aimed at the data of this module. Destructuring handles products — {:ok, v} binds v. Dispatch handles sums — a function head per tag, each handling one variant. Together they make consuming an algebraic value as structured as building it.

Destructuring

A pattern on the left of = binds names to the parts of the value on the right. The pattern’s shape has to fit; where it does, each name takes the matching piece. Pick a pattern.

destructuring
binding names to the parts of a structured value.
clause
one pattern-and-body alternative in a case or function.
dispatch
choosing a clause by the value’s shape, usually its tag.
guard
a when condition that further restricts a clause.

pattern = value · names bind to parts

pattern {:ok, v} value {:ok, 42} binds


      
{:ok, v} = {:ok, 42} · binds v = 42

Idea

A pattern is the shape written out; matching fills its names from the value.

Elixir

A shape that does not fit raises a MatchError — the mismatch is loud.

Destructuring reads a value’s parts by mirroring its shape. The names on the left bind to the pieces on the right.

Dispatch on the tag

Define a function once per variant and the tag chooses which clause runs. area/1 has a head for each shape; calling it with a tagged tuple selects the matching head and binds its fields. Pick a shape and watch its clause activate.

def area(shape) · one head per variant

def area({:circle, r}), do: 3.14159 * r * r def area({:rectangle, w, h}), do: w * h def area({:triangle, b, h}), do: b * h / 2


      
{:circle, 5} · matches head 1, binds r = 5 · 78.54

Idea

The tag routes the call; the head both selects and destructures in one step.

Elixir

Function-head matching is the idiomatic dispatch — often cleaner than a case.

Dispatch is matching at the function head: one clause per tag, each binding that variant’s fields.

Where this goes

That completes F2.07. Products hold fields together and their inhabitants multiply; sums offer variants and their inhabitants add; pattern matching takes both apart — destructuring the products, dispatching on the sums. Most data is a nesting of these, and matching keeps consuming it as orderly as building it. F2.08 turns to joining the functions over this data into pipelines: composition end to end.

Next: F2.08 — Composition & pipelines — building programs by composing functions. Back to the F2.07 hub or the F2 overview.