fp_library/
functions.rs

1//! Generic, helper free functions and re-exports of free versions
2//! of type class functions.
3//!
4//! This module provides a collection of utility functions commonly found in functional programming,
5//! such as function composition, constant functions, and identity functions. It also re-exports
6//! free function versions of methods defined in various type classes (traits) for convenience.
7//!
8//! ### Examples
9//!
10//! ```
11//! use fp_library::{brands::*, functions::*};
12//!
13//! let f = |x: i32| x + 1;
14//! let g = |x: i32| x * 2;
15//! let h = compose::<i32, i32, _, _, _>(f, g);
16//!
17//! assert_eq!(map::<OptionBrand, _, _, _>(h, Some(5)), Some(11));
18//! ```
19
20// Auto-generate re-exports, passing in aliases for conflicting names.
21fp_macros::generate_function_re_exports!("src/classes", {
22	"category::identity": category_identity,
23	"cloneable_fn::new": cloneable_fn_new,
24	"function::new": fn_new,
25	"once::new": once_new,
26	"once::get": once_get,
27	"once::get_mut": once_get_mut,
28	"once::set": once_set,
29	"once::get_or_init": once_get_or_init,
30	"once::into_inner": once_into_inner,
31	"once::take": once_take,
32	"pointer::new": pointer_new,
33	"ref_counted_pointer::cloneable_new": ref_counted_pointer_new,
34	"send_ref_counted_pointer::send_new": send_ref_counted_pointer_new,
35	"semigroupoid::compose": semigroupoid_compose,
36	"send_cloneable_fn::new": send_cloneable_fn_new,
37	"thunk_wrapper::new": thunk_wrapper_new,
38	"thunk_wrapper::take": thunk_wrapper_take,
39});
40
41/// Composes two functions.
42///
43/// Takes two functions, `f` and `g`, and returns a new function that applies `g` to its argument,
44/// and then applies `f` to the result. This is equivalent to the mathematical composition `f ∘ g`.
45///
46/// ### Type Signature
47///
48/// `forall a c b. (b -> c, a -> b) -> (a -> c)`
49///
50/// ### Type Parameters
51///
52/// * `A`: The input type of the inner function `g`.
53/// * `C`: The output type of the outer function `f`.
54/// * `B`: The output type of `g` and the input type of `f`.
55/// * `F`: The type of the outer function.
56/// * `G`: The type of the inner function.
57///
58/// ### Parameters
59///
60/// * `f`: The outer function to apply second.
61/// * `g`: The inner function to apply first.
62///
63/// ### Returns
64///
65/// A new function that takes an `A` and returns a `C`.
66///
67/// ### Examples
68///
69/// ```rust
70/// use fp_library::functions::*;
71///
72/// let add_one = |x: i32| x + 1;
73/// let times_two = |x: i32| x * 2;
74/// let times_two_add_one = compose::<i32, i32, _, _, _>(add_one, times_two);
75///
76/// // 3 * 2 + 1 = 7
77/// assert_eq!(
78///     times_two_add_one(3),
79///     7
80/// );
81/// ```
82pub fn compose<A, C, B, F, G>(
83	f: F,
84	g: G,
85) -> impl Fn(A) -> C
86where
87	F: Fn(B) -> C,
88	G: Fn(A) -> B,
89{
90	move |a| f(g(a))
91}
92
93/// Creates a constant function.
94///
95/// Returns a function that ignores its argument and always returns the provided value `a`.
96/// This is useful when a function is expected but a constant value is needed.
97///
98/// ### Type Signature
99///
100/// `forall b a. a -> (b -> a)`
101///
102/// ### Type Parameters
103///
104/// * `B`: The type of the argument to ignore.
105/// * `A`: The type of the value to return.
106///
107/// ### Parameters
108///
109/// * `a`: The value to be returned by the constant function.
110///
111/// ### Returns
112///
113/// A function that takes any value of type `B` and returns `a`.
114///
115/// ### Examples
116///
117/// ```rust
118/// use fp_library::functions::*;
119///
120/// assert_eq!(
121///     constant::<bool, _>(true)(false),
122///     true
123/// );
124/// ```
125pub fn constant<B, A: Clone>(a: A) -> impl Fn(B) -> A {
126	move |_| a.clone()
127}
128
129/// Flips the arguments of a binary function.
130///
131/// Returns a new function that takes its arguments in the reverse order of the input function `f`.
132/// If `f` takes `(a, b)`, the returned function takes `(b, a)`.
133///
134/// ### Type Signature
135///
136/// `forall a b c. ((a, b) -> c) -> ((b, a) -> c)`
137///
138/// ### Type Parameters
139///
140/// * `A`: The type of the first argument of the input function.
141/// * `B`: The type of the second argument of the input function.
142/// * `C`: The return type of the function.
143/// * `F`: The type of the input binary function.
144///
145/// ### Parameters
146///
147/// * `f`: A binary function.
148///
149/// ### Returns
150///
151/// A version of `f` that takes its arguments in reverse.
152///
153/// ### Examples
154///
155/// ```rust
156/// use fp_library::functions::*;
157///
158/// let subtract = |a, b| a - b;
159///
160/// // 0 - 1 = -1
161/// assert_eq!(
162///     flip::<i32, i32, _, _>(subtract)(1, 0),
163///     -1
164/// );
165/// ```
166pub fn flip<A, B, C, F>(f: F) -> impl Fn(B, A) -> C
167where
168	F: Fn(A, B) -> C,
169{
170	move |b, a| f(a, b)
171}
172
173/// The identity function.
174///
175/// Returns its input argument as is. This is often used as a default or placeholder function.
176///
177/// ### Type Signature
178///
179/// `forall a. a -> a`
180///
181/// ### Type Parameters
182///
183/// * `A`: The type of the value.
184///
185/// ### Parameters
186///
187/// * `a`: A value.
188///
189/// ### Returns
190///
191/// The same value `a`.
192///
193/// ### Examples
194///
195/// ```rust
196/// use fp_library::functions::*;
197///
198/// assert_eq!(
199///     identity(()),
200///     ()
201/// );
202/// ```
203pub fn identity<A>(a: A) -> A {
204	a
205}