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}