Expand description
§fp-library
A functional programming library for Rust featuring your favourite higher-kinded types and type classes.
§Motivation
Rust is a multi-paradigm language with strong functional programming features like iterators, closures, and algebraic data types. However, it lacks native support for Higher-Kinded Types (HKT), which limits the ability to write generic code that abstracts over type constructors (e.g., writing a function that works for any Monad, whether it’s Option, Result, or Vec).
fp-library aims to bridge this gap by providing:
- A robust encoding of HKTs in stable Rust.
- A comprehensive set of standard type classes (
Functor,Monad,Traversable, etc.). - Zero-cost abstractions that respect Rust’s performance characteristics.
§Examples
§Using Functor with Option
The brand is inferred automatically from the container type:
use fp_library::functions::*;
// Brand inferred from Option<i32>
let y = map(|i: i32| i * 2, Some(5));
assert_eq!(y, Some(10));
// Brand inferred from &Vec<i32> (by-reference dispatch)
let v = vec![1, 2, 3];
let y = map(|i: &i32| *i + 10, &v);
assert_eq!(y, vec![11, 12, 13]);For types with multiple brands (e.g., Result), use the explicit variant:
use fp_library::{
brands::*,
functions::explicit::*,
};
let y = map::<ResultErrAppliedBrand<&str>, _, _, _, _>(|i| i * 2, Ok::<i32, &str>(5));
assert_eq!(y, Ok(10));§Monadic Do-Notation with m_do!
The m_do! macro provides Haskell/PureScript-style do-notation for flat monadic code.
It desugars <- binds into nested bind calls.
use fp_library::{brands::*, functions::*, m_do};
// Inferred mode: brand inferred from container types
let result = m_do!({
x <- Some(5);
y <- Some(x + 1);
let z = x * y;
Some(z)
});
assert_eq!(result, Some(30));
// Explicit mode: for ambiguous types or when pure() is needed
let result = m_do!(VecBrand {
x <- vec![1, 2];
y <- vec![10, 20];
pure(x + y)
});
assert_eq!(result, vec![11, 21, 12, 22]);§Features
For a detailed breakdown of all features, type class hierarchies, data types, and macros, see the Features documentation.
§How it Works
Higher-Kinded Types: The library encodes HKTs using lightweight higher-kinded polymorphism
(the “Brand” pattern). Each type constructor has a zero-sized brand type (e.g., OptionBrand)
that implements Kind traits mapping brands back to concrete types.
See Higher-Kinded Types.
Brand Inference: InferableBrand traits provide the reverse mapping (concrete type -> brand),
letting the compiler infer brands automatically. trait_kind! and impl_kind! generate both
mappings. See Brand Inference.
Val/Ref Dispatch: Each free function routes to either a by-value or by-reference trait method
based on the closure’s argument type (or container ownership for closureless operations). Dispatch
and brand inference compose through the shared FA type parameter.
See Val/Ref Dispatch.
Zero-Cost Abstractions: Core operations use uncurried semantics with impl Fn for static
dispatch and zero heap allocation. Dynamic dispatch (dyn Fn) is reserved for cases where
functions must be stored as data.
See Zero-Cost Abstractions.
Lazy Evaluation: A granular hierarchy of lazy types (Thunk, Trampoline, Lazy) lets you
choose trade-offs between stack safety, memoization, lifetimes, and thread safety. Each has a
fallible Try* counterpart.
See Lazy Evaluation.
Thread Safety & Parallelism: A parallel trait hierarchy (ParFunctor, ParFoldable, etc.)
mirrors the sequential one. When the rayon feature is enabled, par_* functions use true
parallel execution.
See Thread Safety and Parallelism.
§Documentation
- Features & Type Class Hierarchy
- Higher-Kinded Types
- Brand Inference
- Val/Ref Dispatch
- Zero-Cost Abstractions
- Pointer Abstraction
- Lazy Evaluation
- Coyoneda Implementations
- Thread Safety & Parallelism
- Limitations and Workarounds
- Project Structure
- Architecture & Design
- Optics Analysis
- Profunctor Analysis
- Std Library Coverage
§Crate Features
rayon: Enables true parallel execution forpar_*functions using the rayon library. Without this feature,par_*functions fall back to sequential equivalents.serde: Enables serialization and deserialization support for pure data types using the serde library.stacker: Enables adaptive stack growth for deepCoyoneda,RcCoyoneda, andArcCoyonedamap chains via the stacker crate. Without this feature, deeply chained maps can overflow the stack.
Modules§
- brands
- Brands represent higher-kinded (unapplied/partially-applied) forms of types, as opposed to concrete types, which are fully-applied.
- classes
- Defines traits for common algebraic structures and functional abstractions,
such as
Functor,ApplicativeandMonad. - dispatch
- Dispatch infrastructure for unified free functions that route to either by-value or by-reference trait methods based on the closure’s argument type.
- docs
- Design documentation for fp-library.
- functions
- The primary API for calling type class operations as free functions.
- kinds
KindandInferableBrandtraits for higher-kinded type simulation.- types
- Concrete data types, their corresponding implementations and type aliases.
Macros§
- Apply
- Applies a brand to type arguments.
- Inferable
Brand - Generates the name of an
InferableBrandtrait based on its signature. - Kind
- Generates the name of a
Kindtrait based on its signature. - a_do
- Applicative do-notation.
- doc_
include - Includes a markdown file with relative
.mdlinks rewritten to rustdoc intra-doc links. - generate_
function_ re_ exports - Generates re-exports for all public free functions in a directory.
- generate_
trait_ re_ exports - Generates re-exports for all public traits in a directory.
- impl_
kind - Implements a
Kindtrait and itsInferableBrandtrait for a brand. - m_do
- Monadic do-notation.
- trait_
kind - Defines a new
Kindtrait and its correspondingInferableBrandtrait.
Attribute Macros§
- document_
examples - Inserts a
### Examplesheading and validates doc comment code blocks. - document_
module - Orchestrates documentation generation for an entire module.
- document_
parameters - Generates documentation for a function’s parameters.
- document_
returns - Generates documentation for the return value of a function.
- document_
signature - Generates a Hindley-Milner style type signature for a function.
- document_
type_ parameters - Generates documentation for type parameters.
- kind
- Adds a
Kindsupertrait bound to a trait definition.