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