fp_library/
functions.rs

1//! Generic, helper free functions and re-exports of free versions
2//! of type class functions.
3
4pub use crate::classes::{
5	apply_first::apply_first,
6	apply_second::apply_second,
7	category::identity as category_identity,
8	foldable::{fold_left, fold_map, fold_right},
9	functor::map,
10	monoid::empty,
11	pointed::pure,
12	semiapplicative::apply,
13	semigroup::append,
14	semigroupoid::compose as semigroupoid_compose,
15	semimonad::bind,
16	traversable::{sequence, traverse},
17};
18
19/// Takes functions `f` and `g` and returns the function `f . g` (`f` composed with `g`).
20///
21/// # Type Signature
22///
23/// `forall a b c. (b -> c) -> (a -> b) -> a -> c`
24///
25/// # Parameters
26///
27/// * `f`: A function from values of type `B` to values of type `C`.
28/// * `g`: A function from values of type `A` to values of type `B`.
29///
30/// # Returns
31///
32/// A function from values of type `A` to values of type `C`.
33///
34/// # Examples
35///
36/// ```rust
37/// use fp_library::functions::compose;
38///
39/// let add_one = |x: i32| x + 1;
40/// let times_two = |x: i32| x * 2;
41/// let times_two_add_one = compose(add_one, times_two);
42///
43/// // 3 * 2 + 1 = 7
44/// assert_eq!(
45///     times_two_add_one(3),
46///     7
47/// );
48/// ```
49pub fn compose<A, B, C, F, G>(
50	f: F,
51	g: G,
52) -> impl Fn(A) -> C
53where
54	F: Fn(B) -> C,
55	G: Fn(A) -> B,
56{
57	move |a| f(g(a))
58}
59
60/// Returns its first argument.
61///
62/// # Type Signature
63///
64/// `forall a b. a -> b -> a`
65///
66/// # Parameters
67///
68/// * `a`: A value.
69/// * `b`: Some other value.
70///
71/// # Returns
72///
73/// The first value.
74///
75/// # Examples
76///
77/// ```rust
78/// use fp_library::functions::constant;
79///
80/// assert_eq!(
81///     constant(true)(false),
82///     true
83/// );
84/// ```
85pub fn constant<A: Clone, B>(a: A) -> impl Fn(B) -> A {
86	move |_| a.clone()
87}
88
89/// Returns a version of the input binary function with its arguments flipped.
90///
91/// # Type Signature
92///
93/// `forall a b c. (a -> b -> c) -> b -> a -> c`
94///
95/// # Parameters
96///
97/// * `f`: A binary function.
98///
99/// # Returns
100///
101/// A version of `f` that takes its arguments in reverse.
102///
103/// # Examples
104///
105/// ```rust
106/// use fp_library::functions::flip;
107///
108/// let subtract = |a, b| a - b;
109///
110/// // 0 - 1 = -1
111/// assert_eq!(
112///     flip(subtract)(1, 0),
113///     -1
114/// );
115/// ```
116pub fn flip<A, B, C, F>(f: F) -> impl Fn(B, A) -> C
117where
118	F: Fn(A, B) -> C,
119{
120	move |b, a| f(a, b)
121}
122
123/// Returns its input.
124///
125/// # Type Signature
126///
127/// `forall a. a -> a`
128///
129/// # Parameters
130///
131/// * `a`: A value.
132///
133/// # Returns
134///
135/// The same value.
136///
137/// # Examples
138///
139/// ```rust
140/// use fp_library::functions::identity;
141///
142/// assert_eq!(
143///     identity(()),
144///     ()
145/// );
146/// ```
147pub fn identity<A>(a: A) -> A {
148	a
149}