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
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
//! # 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:
//!
//! 1. A robust encoding of HKTs in stable Rust.
//! 2. A comprehensive set of standard type classes (`Functor`, `Monad`, `Traversable`, etc.).
//! 3. 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`](functions::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]);
//! ```
//!
//! ## How it Works
//!
//! ## Crate Features
//!
//! - **`rayon`**: Enables true parallel execution for `par_*` functions using the [rayon](https://github.com/rayon-rs/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](https://github.com/serde-rs/serde) library.
//! - **`stacker`**: Enables adaptive stack growth for deep `Coyoneda`, `RcCoyoneda`, and `ArcCoyoneda` map chains via the [stacker](https://github.com/rust-lang/stacker) crate. Without this feature, deeply chained maps can overflow the stack.
extern crate fp_macros;
pub
pub use *;