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