fp_library/classes/
apply_second.rs

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