ExamplesBy LevelBy TopicLearning Paths
232 Intermediate

Sum Types

Functional Programming

Tutorial Video

Text description (accessibility)

This video demonstrates the "Sum Types" functional Rust example. Difficulty level: Intermediate. Key concepts covered: Functional Programming. A sum type (also called a tagged union, discriminated union, or variant type) holds a value of exactly one of several possible types. Key difference from OCaml: 1. **Syntax**: OCaml's `type t = A | B of int` vs. Rust's `enum T { A, B(i32) }` — structurally identical, syntactically different.

Tutorial

The Problem

A sum type (also called a tagged union, discriminated union, or variant type) holds a value of exactly one of several possible types. Result<T, E> holds either a T or an E. Option<T> holds either a T or nothing. A Shape holds either a Circle or a Rectangle. Sum types are the fundamental mechanism for modeling data with alternatives, replacing nullable pointers, error codes, and untagged unions with type-safe, exhaustively checkable alternatives.

🎯 Learning Outcomes

  • • Understand sum types as the dual of product types: "this OR that" vs. "this AND that"
  • • Learn how Rust enums implement sum types with associated data
  • • See exhaustive pattern matching as the consumer of sum types
  • • Understand the type algebra: |A| + |B| inhabitants for Either<A, B>
  • Code Example

    #![allow(clippy::all)]
    // Stub — awaiting conversion from OCaml source.

    Key Differences

  • Syntax: OCaml's type t = A | B of int vs. Rust's enum T { A, B(i32) } — structurally identical, syntactically different.
  • Polymorphic variants: OCaml's ` [> A | B] provides open sum types; Rust's enums are always closed (unless #[non_exhaustive]). 3. **Exhaustiveness**: Both require exhaustive matching; OCaml warns by default, errors with flags; Rust errors by default. 4. **Data attachment**: Both allow per-variant associated data with arbitrary types; OCaml's tuple syntax A of int * string vs. Rust's A(i32, String)` or named fields.
  • OCaml Approach

    OCaml's variant types are the original inspiration for Rust's enums:

    type shape = Circle of float | Rect of float * float
    let area = function
      | Circle r -> Float.pi *. r *. r
      | Rect (w, h) -> w *. h
    

    OCaml's variants are exhaustively matched with match — unhandled cases produce a warning (or error with -w +8). OCaml also has polymorphic variants (` Circle ``...) for open-world sum types that can be extended without modifying the original type.

    Full Source

    #![allow(clippy::all)]
    // Stub — awaiting conversion from OCaml source.

    Deep Comparison

    OCaml vs Rust: Sum Types

    Overview

    See the example.rs and example.ml files for detailed implementations.

    Key Differences

    AspectOCamlRust
    Type systemHindley-MilnerOwnership + traits
    MemoryGCZero-cost abstractions
    MutabilityExplicit refmut keyword
    Error handlingOption/ResultResult<T, E>

    See README.md for detailed comparison.

    Exercises

  • Define a Token sum type for a simple expression language: Int(i64), Plus, Minus, LParen, RParen.
  • Implement eval: Expr -> i64 for a recursive Expr type using exhaustive pattern matching.
  • Add #[non_exhaustive] to a public enum and verify that downstream matches require a wildcard arm.
  • Open Source Repos