jonnifyelixir
F1 · Algebra / F1.04 / F1.05

F1 · Algebra

Sets, sequences & mappings

A single value is rarely the whole story. Three shapes of collection cover almost everything — ordered sequences, distinct sets, and key-to-value mappings — and one operation runs a function across any of them.

Each shape answers a different question: in what order, how many distinct, and looked up by what. Once the elements are immutable values from F1.04, the collections holding them are immutable too. We meet the three, then apply a function across a collection with map — the operation the next chapters build on.

Sequence and set

A sequence keeps order and keeps repeats: it is a row of elements where position matters and the same value may appear twice. A set keeps neither: it records only which distinct values are present, with no order and no count. The same elements poured into each give different things.

Take elements one at a time and compare. The sequence grows with every element; the set grows only when a value it has not seen arrives.

sequence
ordered, duplicates kept — an Elixir List, like [3, 1, 4].
set
unordered, distinct only — an Elixir MapSet.
mapping
keys to values, keys unique — an Elixir Map, like %{a: 1}.
membership
whether a value is in a set — x ∈ S — ignoring order and count.

Same elements · sequence versus set

5
list 3 1 4 1 5 set 3 1 4 5


      
list — length 5 (order & duplicates kept) · set — size 4 · one duplicate dropped

Algebra

A sequence is an ordered list with repeats; a set is {distinct} with neither order nor count.

Elixir

[3, 1, 4, 1] is a list; MapSet.new([3, 1, 4, 1]) holds {1, 3, 4}.

Choose the shape by the question you are asking: order and repeats, or distinct membership. They are different tools, not interchangeable ones.

Mapping over a collection

The operation that ties collections to functions is map: apply a function to every element and collect the results into a new collection of the same shape and size. It changes the contents, never the structure — a list of four maps to a list of four — and, true to F1.04, it returns a new collection rather than altering the old one.

Pick a function and run it across the list.

Enum.map · apply f to every element

1 2 3 4 f = x² 1 4 9 16


      
[1, 2, 3, 4] → [1, 4, 9, 16] · length preserved (4 → 4) · a new list is returned

Algebra

Apply f to each member of a collection to get the collection of images.

Elixir

Enum.map([1, 2, 3, 4], f) returns a new list, one image per element.

Map is the bridge from F1.01’s single function to whole collections, and it preserves the shape it works on. F1.07 adds the operators that change the shape — filter and reduce.

A mapping is a function

The third shape closes a loop. A mapping stores keys against values, and that is exactly what a finite function is — a table of input to output. Looking a key up in a map is calling that function. A map is a partial function: it answers for the keys it holds and reports nothing for the rest, which is why a lookup returns either the value or a clear absence.

Look up a key in a small map of squares.

A map of squares · look up a key

3
squares 1 → 1 2 → 4 3 → 9 4 → 16 Map.get(squares, 3) 9


      
Map.get(squares, 3) → 9 · the key is present

Algebra

A finite function is a set of input-to-output pairs — a lookup table.

Elixir

Map.get/2 calls that table; a missing key returns nil (or a default).

A map is a function you can hold in your hand, and a lookup is a call. The single-output rule of F1.01 is why a key can map to exactly one value.

What this lands

Three shapes, one for each question: a sequence for order and repeats, a set for distinct membership, a mapping for lookup by key — each an immutable value in the sense of F1.04. The operation that unites them is map, which applies a function across a collection and returns a new one, carrying F1.01’s single function out to many elements. And the mapping shape turns out to be a finite function itself. From here, F1.06 shows how to build and traverse these collections with recursion, and F1.07 adds filter and reduce to reshape them.

Next: F1.06 — Recursion & induction (planned) — base case and step, the way functional code traverses a collection without a loop. The rest of F1 is on the chapter page.