fp_library/
functions.rs

1//! Generic, helper free functions, combinators and re-exports of [typeclass][crate::typeclasses]
2//! free functions that dispatch to associated functions of typeclass instances.
3
4use crate::aliases::ArcFn;
5pub use crate::typeclasses::{
6	apply::apply,
7	apply_first::apply_first,
8	apply_second::apply_second,
9	bind::bind,
10	foldable::{fold_left, fold_map, fold_right},
11	functor::map,
12	monoid::empty,
13	pure::pure,
14	semigroup::append,
15	traversable::{sequence, traverse},
16};
17use std::sync::Arc;
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/// use std::sync::Arc;
39///
40/// let add_one = Arc::new(|x: i32| x + 1);
41/// let times_two = Arc::new(|x: i32| x * 2);
42/// let times_two_add_one = compose(add_one)(times_two);
43///
44/// // 3 * 2 + 1 = 7
45/// assert_eq!(
46///     times_two_add_one(3),
47///     7
48/// );
49/// ```
50pub fn compose<'a, A: 'a, B: 'a, C: 'a>(
51	f: ArcFn<'a, B, C>
52) -> ArcFn<'a, ArcFn<'a, A, B>, ArcFn<'a, A, C>> {
53	Arc::new(move |g| {
54		let f = f.clone();
55		Arc::new(move |a| f(g(a)))
56	})
57}
58
59/// Returns its first argument.
60///
61/// # Type Signature
62///
63/// `forall a b. a -> b -> a`
64///
65/// # Parameters
66///
67/// * `a`: A value.
68/// * `b`: Some other value.
69///
70/// # Returns
71///
72/// The first value.
73///
74/// # Examples
75///
76/// ```rust
77/// use fp_library::{functions::constant};
78///
79/// assert_eq!(
80///     constant(true)(false),
81///     true
82/// );
83/// ```
84pub fn constant<'a, A: 'a + Clone, B: Clone>(a: A) -> ArcFn<'a, B, A> {
85	Arc::new(move |_b| a.to_owned())
86}
87
88/// Returns a version of the input curried binary function
89/// 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 curried 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::{aliases::ArcFn, functions::flip};
107/// use std::sync::Arc;
108///
109/// let subtract: ArcFn<_, ArcFn<_, _>> = Arc::new(|a| Arc::new(move |b| a - b));
110///
111/// // 0 - 1 = -1
112/// assert_eq!(
113///     flip(subtract)(1)(0),
114///     -1
115/// );
116/// ```
117pub fn flip<'a, A: 'a, B: 'a + Clone, C: 'a>(
118	f: ArcFn<'a, A, ArcFn<'a, B, C>>
119) -> ArcFn<'a, B, ArcFn<'a, A, C>> {
120	Arc::new(move |b| {
121		let f = f.clone();
122		Arc::new(move |a| (f(a))(b.to_owned()))
123	})
124}
125
126/// Returns its input.
127///
128/// # Type Signature
129///
130/// `forall a. a -> a`
131///
132/// # Parameters
133///
134/// * `a`: A value.
135///
136/// # Returns
137///
138/// The same value.
139///
140/// # Examples
141///
142/// ```rust
143/// use fp_library::functions::identity;
144///
145/// assert_eq!(
146///     identity(()),
147///     ()
148/// );
149/// ```
150pub fn identity<A>(a: A) -> A {
151	a
152}