Sum types
Sum types, in the reference of the Soma programming language (soma 3.2.4). A block marked ✓ is a whole program that soma check accepts; the others are excerpts.
// `cell type` + `variants` = tagged union. Struct, tuple, or bare variants.
cell type PaymentResult {
variants {
Charged { transaction_id: String, amount: Int } // struct variant
Declined(String) // tuple variant
Pending // unit variant
}
}
// Construct directly — bare variants take no parentheses:
on charge(amount: Int) {
if amount > 0 { return Charged { transaction_id: "tx-1", amount: amount } }
if amount == 0 { return Pending }
return Declined("non-positive amount")
}
// match is EXHAUSTIVE — missing a variant is a compile error:
on describe(r: Map) {
return match r {
Charged { transaction_id, amount } -> "ok {transaction_id} ${amount}"
Declined(reason) -> "rejected: {reason}"
Pending -> "..."
}
}A complete Soma program: soma check passes on it (soma 3.2.4).
// Typed state machine: states must be variants of the sum type,
// and transition() takes a variant (typo = compile error):
cell type TodoStatus {
variants { Pending InProgress Done Cancelled }
}
cell TodoList {
state todo: TodoStatus {
initial: Pending
Pending -> InProgress
InProgress -> Done
* -> Cancelled
}
on start(id: String) {
transition(id, InProgress) // variant, not string
return get_status(id) // "InProgress"
}
}