1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
//! Free Monads and Tagless Final - DSL Interpreters
//!
//! > *"Libertas est potestas faciendi id quod iure licet."*
//! > — Freedom is the power to do what is permitted by law.
//!
//! This module provides Free monads and Tagless Final patterns for
//! building and interpreting domain-specific languages (DSLs).
//!
//! # Core Concepts
//!
//! ## Free Monad
//!
//! The Free monad `Liber<F, A>` builds a monad from any functor `F`.
//! It represents a computation that can be interpreted in multiple ways.
//!
//! ## Freer Monad
//!
//! The Freer monad `Liberior<F, A>` is more efficient - it doesn't
//! require `F` to be a Functor, using defunctionalization instead.
//!
//! ## Tagless Final
//!
//! Tagless Final represents DSLs as traits (algebras) rather than
//! data structures. This enables extensibility and multiple interpreters.
//!
//! # Scholastic Naming
//!
//! | Concept | Latin Name | Etymology |
//! |---------|------------|-----------|
//! | Free Monad | Liber | *liber* = free |
//! | Freer Monad | Liberior | *liberior* = more free |
//! | Natural Transformation | `TransformatioNaturalis` | *transformatio* = change of form |
//! | Algebra | Algebra | Arabic *al-jabr* = reunion of broken parts |
//! | Interpreter | Interpres | *interpres* = explainer, translator |
//!
//! # Example
//!
//! ```rust
//! use ordofp_core::free::*;
//!
//! // Build a program using the Free monad over the `Option` functor
//! let program: Liber<OptionFWitness, i32> = Liber::purus(42);
//!
//! // Interpret it via the identity natural transformation back to `Option`
//! let result = plica_liber::<OptionFWitness, OptionFWitness, i32, _>(|fa| fa, program);
//! assert_eq!(result, Some(42));
//! ```
extern crate alloc;
pub use *;
pub use *;
pub use *;
pub use *;
pub use *;