fp_library/classes/apply_first.rs
1//! Sequencing of two computations while keeping the result of the first.
2//!
3//! ### Examples
4//!
5//! ```
6//! use fp_library::{brands::*, functions::*};
7//!
8//! let x = Some(5);
9//! let y = Some(10);
10//! let z = apply_first::<OptionBrand, _, _>(x, y);
11//! assert_eq!(z, Some(5));
12//! ```
13
14use super::lift::Lift;
15use crate::{Apply, kinds::*};
16use fp_macros::doc_params;
17use fp_macros::doc_type_params;
18use fp_macros::hm_signature;
19
20/// A type class for types that support combining two contexts, keeping the first value.
21///
22/// `ApplyFirst` provides the ability to sequence two computations but discard
23/// the result of the second computation, keeping only the result of the first.
24pub trait ApplyFirst: Lift {
25 /// Combines two contexts, keeping the value from the first context.
26 ///
27 /// This function sequences two computations and discards the result of the second computation, keeping only the result of the first.
28 ///
29 /// ### Type Signature
30 ///
31 #[hm_signature(ApplyFirst)]
32 ///
33 /// ### Type Parameters
34 ///
35 #[doc_type_params(
36 "The lifetime of the values.",
37 "The type of the value in the first context.",
38 "The type of the value in the second context."
39 )]
40 ///
41 /// ### Parameters
42 ///
43 #[doc_params("The first context.", "The second context.")]
44 ///
45 /// ### Returns
46 ///
47 /// The first context.
48 ///
49 /// ### Examples
50 ///
51 /// ```
52 /// use fp_library::{brands::*, functions::*};
53 ///
54 /// let x = Some(5);
55 /// let y = Some(10);
56 /// let z = apply_first::<OptionBrand, _, _>(x, y);
57 /// assert_eq!(z, Some(5));
58 /// ```
59 fn apply_first<'a, A: 'a + Clone, B: 'a + Clone>(
60 fa: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
61 fb: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>),
62 ) -> Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>) {
63 Self::lift2(|a, _| a, fa, fb)
64 }
65}
66
67/// Combines two contexts, keeping the value from the first context.
68///
69/// Free function version that dispatches to [the type class' associated function][`ApplyFirst::apply_first`].
70///
71/// ### Type Signature
72///
73#[hm_signature(ApplyFirst)]
74///
75/// ### Type Parameters
76///
77#[doc_type_params(
78 "The lifetime of the values.",
79 "The brand of the context.",
80 "The type of the value in the first context.",
81 "The type of the value in the second context."
82)]
83///
84/// ### Parameters
85///
86#[doc_params("The first context.", "The second context.")]
87///
88/// ### Returns
89///
90/// The first context.
91///
92/// ### Examples
93///
94/// ```
95/// use fp_library::{brands::*, functions::*};
96///
97/// let x = Some(5);
98/// let y = Some(10);
99/// let z = apply_first::<OptionBrand, _, _>(x, y);
100/// assert_eq!(z, Some(5));
101/// ```
102pub fn apply_first<'a, Brand: ApplyFirst, A: 'a + Clone, B: 'a + Clone>(
103 fa: Apply!(<Brand as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
104 fb: Apply!(<Brand as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>),
105) -> Apply!(<Brand as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>) {
106 Brand::apply_first(fa, fb)
107}