ExamplesBy LevelBy TopicLearning Paths
247 Expert

Limits and Colimits

Functional Programming

Tutorial Video

Text description (accessibility)

This video demonstrates the "Limits and Colimits" functional Rust example. Difficulty level: Expert. Key concepts covered: Functional Programming. Limits and colimits are the categorical generalizations of "greatest lower bounds" and "least upper bounds." Products, terminal objects, equalizers, and pullbacks are all limits; coproducts, initial objects, coequalizers, and pushouts are all colimits. Key difference from OCaml: | Concept | Rust | OCaml |

Tutorial

The Problem

Limits and colimits are the categorical generalizations of "greatest lower bounds" and "least upper bounds." Products, terminal objects, equalizers, and pullbacks are all limits; coproducts, initial objects, coequalizers, and pushouts are all colimits. In type theory and functional programming, they correspond to familiar constructs: product types (limits), sum types (colimits), function spaces, and more. This example instantiates categorical limits and colimits as Rust types and shows the universal property that characterizes each.

🎯 Learning Outcomes

  • • Identify products, coproducts, equalizers, and pullbacks as categorical limits/colimits
  • • Implement the universal property (unique morphism) for products and coproducts in Rust
  • • See how (A, B) is the limit of the diagram A ← • → B
  • • See how Either<A, B> is the colimit of the same diagram
  • • Compare categorical constructions with OCaml's type-theoretic encodings
  • Code Example

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

    Key Differences

    ConceptRustOCaml
    Product(A, B) tuplerecord or tuple
    Coproductenum Either<A,B>type ('a,'b) either
    Terminal() unitunit
    Initial! (never, unstable)type empty = \|
    EqualizerVec filterList.filter
    Pullbacknested filterList.concat_map

    Limits/colimits are why product types and sum types look the way they do: they are the unique objects satisfying universal properties up to isomorphism.

    OCaml Approach

    OCaml types directly embody limits and colimits:

    (* Product = record/tuple *)
    let product_univ fst snd c = (fst c, snd c)
    
    (* Coproduct = variant *)
    let coprod_univ inl inr = function
      | Left a  -> inl a
      | Right b -> inr b
    
    (* Equalizer = filtered list via List.filter *)
    let equalizer f g xs = List.filter (fun x -> f x = g x) xs
    
    (* Pullback = cartesian product filtered *)
    let pullback f g xs ys =
      List.concat_map (fun x ->
        List.filter_map (fun y ->
          if f x = g y then Some (x, y) else None) ys) xs
    

    OCaml's type system makes the connection more transparent; Rust requires more scaffolding to express the same categorical ideas.

    Full Source

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

    Deep Comparison

    OCaml vs Rust: Limits Colimits

    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

  • Implement a type-level product and coproduct using a custom Either<L,R> enum and verify the universal property functions type-check.
  • Encode the pushout (dual of pullback) as a type: given A <- C -> B, the pushout is a type that merges A and B while identifying the images of C.
  • Show that Option<A> is the coproduct A + () by implementing from_option and to_option witnessing the isomorphism.
  • Implement the limit of a chain diagram A₀ <- A₁ <- A₂ <- ... (inverse limit) as a type of compatible sequences.
  • Prove that right adjoints preserve limits and left adjoints preserve colimits by showing a concrete example in Rust.
  • Open Source Repos