Fixed-Point Types
Tutorial Video
Text description (accessibility)
This video demonstrates the "Fixed-Point Types" functional Rust example. Difficulty level: Fundamental. Key concepts covered: Functional Programming. A fixed point of a type function F is a type T where T = F(T). Key difference from OCaml: 1. **HKT requirement**: These morphisms ideally require higher
Tutorial
The Problem
A fixed point of a type function F is a type T where T = F(T). In Haskell, Fix F = F (Fix F) captures the recursive structure common to all recursive types. This abstraction enables writing functions over any recursive type generically. In Rust, fixed points require Box or Rc for heap indirection. This pattern is the theoretical foundation for catamorphisms, anamorphisms, and the morphism zoo.
🎯 Learning Outcomes
Code Example
#![allow(clippy::all)]
//! # Fixed-Point Types
//! Recursive types using fixed-point combinators.
pub enum Fix<F> {
In(Box<F>),
}
pub enum ListF<A, R> {
Nil,
Cons(A, R),
}
pub type FixList<A> = Fix<ListF<A, Fix<ListF<A, ()>>>>;
pub fn fold_list<A: Clone, B>(list: &[A], init: B, f: impl Fn(B, &A) -> B) -> B {
list.iter().fold(init, f)
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_fold() {
let sum = fold_list(&[1, 2, 3], 0, |a, b| a + b);
assert_eq!(sum, 6);
}
}Key Differences
recursion-schemes are widely used; in Rust and OCaml, direct recursion is more common in practice.OCaml Approach
OCaml's pattern matching and recursive types make morphism implementations natural. The Fix type and F-algebra/coalgebra patterns translate directly, though without Haskell's typeclass machinery:
(* OCaml recursive schemes use:
- Recursive variant types for F-algebras
- Higher-order functions for the morphism
- GADTs for type-safe fixed points in advanced cases *)
Full Source
#![allow(clippy::all)]
//! # Fixed-Point Types
//! Recursive types using fixed-point combinators.
pub enum Fix<F> {
In(Box<F>),
}
pub enum ListF<A, R> {
Nil,
Cons(A, R),
}
pub type FixList<A> = Fix<ListF<A, Fix<ListF<A, ()>>>>;
pub fn fold_list<A: Clone, B>(list: &[A], init: B, f: impl Fn(B, &A) -> B) -> B {
list.iter().fold(init, f)
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_fold() {
let sum = fold_list(&[1, 2, 3], 0, |a, b| a + b);
assert_eq!(sum, 6);
}
}#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_fold() {
let sum = fold_list(&[1, 2, 3], 0, |a, b| a + b);
assert_eq!(sum, 6);
}
}
Deep Comparison
Fixed-Point Types
Fix F = F (Fix F) - recursive structure