Skip to main content

Type Algebra

Merge records with + and select fields with [] — Constellation's type algebra operators.

Use Case

You have data from two sources with overlapping fields and need to combine them, then extract a subset.

The Pipeline

# type-algebra.cst - Record merging and projections

# Define record types
type Base = { id: Int, name: String }
type Extra = { name: String, score: Float }

in base: Base
in extra: Extra

# Merge records (right side wins on conflicts)
# Result type: { id: Int, name: String, score: Float }
merged = base + extra

# Project specific fields
# Result type: { id: Int, score: Float }
summary = merged[id, score]

out merged
out summary

Explanation

StepExpressionResult TypePurpose
1base + extra{ id: Int, name: String, score: Float }Merge two records — extra.name overwrites base.name
2merged[id, score]{ id: Int, score: Float }Select only id and score fields

The + operator performs a right-biased merge: when both records have a field with the same name, the right operand's value wins. The [] operator projects (selects) specific fields — the compiler verifies that every listed field exists.

Right-Bias Matters

In a + b, fields from b overwrite same-named fields from a. Order matters when merging records with overlapping field names.

Running the Example

Input

{
"base": { "id": 1, "name": "Alice" },
"extra": { "name": "Alice Smith", "score": 95.5 }
}

Expected Output

{
"merged": { "id": 1, "name": "Alice Smith", "score": 95.5 },
"summary": { "id": 1, "score": 95.5 }
}

Variations

Multi-source merge

type A = { id: Int, name: String }
type B = { email: String }
type C = { role: String, active: Boolean }

in a: A
in b: B
in c: C

full = a + b + c
contact = full[name, email]

out full
out contact

Merge then process

type Profile = { name: String, age: Int }
type Stats = { score: Int, rank: Int }

in profile: Profile
in stats: Stats

combined = profile + stats
display_name = Uppercase(combined.name)
is_top = gt(combined.rank, 0)

out display_name
out is_top
tip

Use projection [field1, field2] immediately after merging to document and enforce the expected output shape.

Best Practices

  1. Be aware of right-bias — when merging a + b, fields from b overwrite same-named fields from a
  2. Use projection to narrow types — projecting after a merge keeps your output shape explicit
  3. Chain merges for multiple sourcesa + b + c merges left to right