soma.cell

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"
    }
}