fp_library/classes/apply_first.rs
1use super::lift::Lift;
2use crate::hkt::Apply1L1T;
3
4/// A type class for types that support combining two contexts, keeping the first value.
5///
6/// `ApplyFirst` provides the ability to sequence two computations but discard
7/// the result of the second computation, keeping only the result of the first.
8pub trait ApplyFirst: Lift {
9 /// Combines two contexts, keeping the value from the first context.
10 ///
11 /// # Type Signature
12 ///
13 /// `forall a b. ApplyFirst f => (f a, f b) -> f a`
14 ///
15 /// # Parameters
16 ///
17 /// * `fa`: The first context.
18 /// * `fb`: The second context.
19 ///
20 /// # Returns
21 ///
22 /// The first context.
23 ///
24 /// # Examples
25 ///
26 /// ```
27 /// use fp_library::classes::apply_first::ApplyFirst;
28 /// use fp_library::brands::OptionBrand;
29 ///
30 /// let x = Some(5);
31 /// let y = Some(10);
32 /// let z = OptionBrand::apply_first(x, y);
33 /// assert_eq!(z, Some(5));
34 /// ```
35 fn apply_first<'a, A: 'a + Clone, B: 'a + Clone>(
36 fa: Apply1L1T<'a, Self, A>,
37 fb: Apply1L1T<'a, Self, B>,
38 ) -> Apply1L1T<'a, Self, A> {
39 Self::lift2(|a, _| a, fa, fb)
40 }
41}
42
43/// Combines two contexts, keeping the value from the first context.
44///
45/// Free function version that dispatches to [the type class' associated function][`ApplyFirst::apply_first`].
46///
47/// # Type Signature
48///
49/// `forall a b. ApplyFirst f => (f a, f b) -> f a`
50///
51/// # Parameters
52///
53/// * `fa`: The first context.
54/// * `fb`: The second context.
55///
56/// # Returns
57///
58/// The first context.
59///
60/// # Examples
61///
62/// ```
63/// use fp_library::classes::apply_first::apply_first;
64/// use fp_library::brands::OptionBrand;
65///
66/// let x = Some(5);
67/// let y = Some(10);
68/// let z = apply_first::<OptionBrand, _, _>(x, y);
69/// assert_eq!(z, Some(5));
70/// ```
71pub fn apply_first<'a, Brand: ApplyFirst, A: 'a + Clone, B: 'a + Clone>(
72 fa: Apply1L1T<'a, Brand, A>,
73 fb: Apply1L1T<'a, Brand, B>,
74) -> Apply1L1T<'a, Brand, A> {
75 Brand::apply_first(fa, fb)
76}