Free Monad with State
Tutorial Video
Text description (accessibility)
This video demonstrates the "Free Monad with State" functional Rust example. Difficulty level: Expert. Key concepts covered: Functional Programming. Combining the free monad pattern with state — a mutable counter, accumulator, or environment — requires threading state through the interpreter. Key difference from OCaml: 1. **State threading**: Both pass state as an accumulator through recursive calls; neither uses mutable state in the interpreter.
Tutorial
The Problem
Combining the free monad pattern with state — a mutable counter, accumulator, or environment — requires threading state through the interpreter. A state-carrying free monad DSL enables programs that read and write state as pure operations, with the actual state management happening in the interpreter. This models how database transactions, accumulating computations, and stateful protocols can be expressed purely and tested without mutable global state.
🎯 Learning Outcomes
Get and Put state operationsCode Example
#![allow(clippy::all)]
// Stub — awaiting conversion from OCaml source.Key Differences
effect Get : int declaration and a single match_with handler.OCaml Approach
OCaml's state monad and free monad can be combined:
type _ state_op =
| Get : (int -> 'a state_op) -> 'a state_op
| Put : int * (unit -> 'a state_op) -> 'a state_op
| Pure : 'a -> 'a state_op
The interpreter run_state : 'a state_op -> int -> 'a * int has the same structure. OCaml 5's effect handlers can express this more directly: effect Get : int and effect Put : int -> unit with an match_with handler that carries state.
Full Source
#![allow(clippy::all)]
// Stub — awaiting conversion from OCaml source.Deep Comparison
OCaml vs Rust: Free Monad State
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
Modify(f: Box<dyn Fn(i32) -> i32>, continuation: ...) operation that applies a function to the state.run_state_with_log(program, state) interpreter that logs each Get and Put operation.