Skip to main content

fp_library/classes/
apply_second.rs

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