Propositions as Types
Tutorial Video
Text description (accessibility)
This video demonstrates the "Propositions as Types" functional Rust example. Difficulty level: Expert. Key concepts covered: Functional Programming. Extending the Curry-Howard correspondence, this example makes the type-as-proposition correspondence concrete with examples: conjunction (product types), disjunction (sum types), implication (function types), negation (function to `!`), and the universal and existential quantifiers (generic types and existential types). Key difference from OCaml: 1. **Existentials**: Rust's `Box<dyn Trait>` is a runtime existential; OCaml's first
Tutorial
The Problem
Extending the Curry-Howard correspondence, this example makes the type-as-proposition correspondence concrete with examples: conjunction (product types), disjunction (sum types), implication (function types), negation (function to !), and the universal and existential quantifiers (generic types and existential types). Seeing familiar type operations through the logical lens reveals why type system design and formal logic are the same discipline.
🎯 Learning Outcomes
∀T. P(T) = fn<T>(...) Box<dyn Trait> or impl TraitOption = "maybe A", Result = "A or E"Code Example
#![allow(clippy::all)]
// Stub — awaiting conversion from OCaml source.Key Differences
Box<dyn Trait> is a runtime existential; OCaml's first-class modules and GADTs provide more expressive existentials.fn<T>); OCaml's polymorphism is implicit (inferred by type inference) — both express ∀T.! is built-in, OCaml uses type void = |.OCaml Approach
OCaml's type algebra mirrors this directly. The type nonrec keyword and abstract types provide the tools. Coq (the proof assistant) was originally designed with OCaml-like syntax specifically because of the Curry-Howard correspondence — proof terms in Coq are OCaml-like programs.
Full Source
#![allow(clippy::all)]
// Stub — awaiting conversion from OCaml source.Deep Comparison
OCaml vs Rust: Propositions Types
Overview
See the example.rs and example.ml files for detailed implementations.
Key Differences
| Aspect | OCaml | Rust |
|---|---|---|
| Type system | Hindley-Milner | Ownership + traits |
| Memory | GC | Zero-cost abstractions |
| Mutability | Explicit ref | mut keyword |
| Error handling | Option/Result | Result<T, E> |
See README.md for detailed comparison.
Exercises
double_negation_intro<A>(a: A) -> impl Fn(impl Fn(A) -> !) -> ! as a type-level proof.De Morgan: (A -> !) -> (B -> !) -> Either<A, B> -> ! — De Morgan's law as a Rust function.fn<A>(f: impl Fn(A) -> A) -> A is uninhabitable (no value of any type can be returned without an A to start with).