Skip to main content

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	"pointer::new": pointer_new,
26	"ref_counted_pointer::cloneable_new": ref_counted_pointer_new,
27	"send_ref_counted_pointer::send_new": send_ref_counted_pointer_new,
28	"semigroupoid::compose": semigroupoid_compose,
29	"send_cloneable_fn::new": send_cloneable_fn_new,
30	"runnable::run": runnable_run,
31});
32
33/// Composes two functions.
34///
35/// Takes two functions, `f` and `g`, and returns a new function that applies `g` to its argument,
36/// and then applies `f` to the result. This is equivalent to the mathematical composition `f ∘ g`.
37///
38/// ### Type Signature
39///
40/// `forall a c b. (b -> c, a -> b) -> (a -> c)`
41///
42/// ### Type Parameters
43///
44/// * `A`: The input type of the inner function `g`.
45/// * `C`: The output type of the outer function `f`.
46/// * `B`: The output type of `g` and the input type of `f`.
47/// * `F`: The type of the outer function.
48/// * `G`: The type of the inner function.
49///
50/// ### Parameters
51///
52/// * `f`: The outer function to apply second.
53/// * `g`: The inner function to apply first.
54///
55/// ### Returns
56///
57/// A new function that takes an `A` and returns a `C`.
58///
59/// ### Examples
60///
61/// ```rust
62/// use fp_library::functions::*;
63///
64/// let add_one = |x: i32| x + 1;
65/// let times_two = |x: i32| x * 2;
66/// let times_two_add_one = compose::<i32, i32, _, _, _>(add_one, times_two);
67///
68/// // 3 * 2 + 1 = 7
69/// assert_eq!(
70///     times_two_add_one(3),
71///     7
72/// );
73/// ```
74pub fn compose<A, C, B, F, G>(
75	f: F,
76	g: G,
77) -> impl Fn(A) -> C
78where
79	F: Fn(B) -> C,
80	G: Fn(A) -> B,
81{
82	move |a| f(g(a))
83}
84
85/// Creates a constant function.
86///
87/// Returns a function that ignores its argument and always returns the provided value `a`.
88/// This is useful when a function is expected but a constant value is needed.
89///
90/// ### Type Signature
91///
92/// `forall b a. a -> (b -> a)`
93///
94/// ### Type Parameters
95///
96/// * `B`: The type of the argument to ignore.
97/// * `A`: The type of the value to return.
98///
99/// ### Parameters
100///
101/// * `a`: The value to be returned by the constant function.
102///
103/// ### Returns
104///
105/// A function that takes any value of type `B` and returns `a`.
106///
107/// ### Examples
108///
109/// ```rust
110/// use fp_library::functions::*;
111///
112/// assert_eq!(
113///     constant::<bool, _>(true)(false),
114///     true
115/// );
116/// ```
117pub fn constant<B, A: Clone>(a: A) -> impl Fn(B) -> A {
118	move |_| a.clone()
119}
120
121/// Flips the arguments of a binary function.
122///
123/// Returns a new function that takes its arguments in the reverse order of the input function `f`.
124/// If `f` takes `(a, b)`, the returned function takes `(b, a)`.
125///
126/// ### Type Signature
127///
128/// `forall a b c. ((a, b) -> c) -> ((b, a) -> c)`
129///
130/// ### Type Parameters
131///
132/// * `A`: The type of the first argument of the input function.
133/// * `B`: The type of the second argument of the input function.
134/// * `C`: The return type of the function.
135/// * `F`: The type of the input binary function.
136///
137/// ### Parameters
138///
139/// * `f`: A binary function.
140///
141/// ### Returns
142///
143/// A version of `f` that takes its arguments in reverse.
144///
145/// ### Examples
146///
147/// ```rust
148/// use fp_library::functions::*;
149///
150/// let subtract = |a, b| a - b;
151///
152/// // 0 - 1 = -1
153/// assert_eq!(
154///     flip::<i32, i32, _, _>(subtract)(1, 0),
155///     -1
156/// );
157/// ```
158pub fn flip<A, B, C, F>(f: F) -> impl Fn(B, A) -> C
159where
160	F: Fn(A, B) -> C,
161{
162	move |b, a| f(a, b)
163}
164
165/// The identity function.
166///
167/// Returns its input argument as is. This is often used as a default or placeholder function.
168///
169/// ### Type Signature
170///
171/// `forall a. a -> a`
172///
173/// ### Type Parameters
174///
175/// * `A`: The type of the value.
176///
177/// ### Parameters
178///
179/// * `a`: A value.
180///
181/// ### Returns
182///
183/// The same value `a`.
184///
185/// ### Examples
186///
187/// ```rust
188/// use fp_library::functions::*;
189///
190/// assert_eq!(
191///     identity(()),
192///     ()
193/// );
194/// ```
195pub fn identity<A>(a: A) -> A {
196	a
197}