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::{brands::*, functions::*};
7//!
8//! let x = Some(5);
9//! let y = Some(10);
10//! let z = apply_second::<OptionBrand, _, _>(x, y);
11//! assert_eq!(z, Some(10));
12//! ```
13
14use super::lift::Lift;
15use crate::{Apply, kinds::*};
16use fp_macros::doc_params;
17use fp_macros::doc_type_params;
18use fp_macros::hm_signature;
19
20/// A type class for types that support combining two contexts, keeping the second value.
21///
22/// `ApplySecond` provides the ability to sequence two computations but discard
23/// the result of the first computation, keeping only the result of the second.
24pub trait ApplySecond: Lift {
25 /// Combines two contexts, keeping the value from the second context.
26 ///
27 /// This function sequences two computations and discards the result of the first computation, keeping only the result of the second.
28 ///
29 /// ### Type Signature
30 ///
31 #[hm_signature(ApplySecond)]
32 ///
33 /// ### Type Parameters
34 ///
35 #[doc_type_params(
36 "The lifetime of the values.",
37 "The type of the value in the first context.",
38 "The type of the value in the second context."
39 )]
40 ///
41 /// ### Parameters
42 ///
43 #[doc_params("The first context.", "The second context.")]
44 ///
45 /// ### Returns
46 ///
47 /// The second context.
48 ///
49 /// ### Examples
50 ///
51 /// ```
52 /// use fp_library::{brands::*, functions::*};
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///
71/// ### Type Signature
72///
73#[hm_signature(ApplySecond)]
74///
75/// ### Type Parameters
76///
77#[doc_type_params(
78 "The lifetime of the values.",
79 "The brand of the context.",
80 "The type of the value in the first context.",
81 "The type of the value in the second context."
82)]
83///
84/// ### Parameters
85///
86#[doc_params("The first context.", "The second context.")]
87///
88/// ### Returns
89///
90/// The second context.
91///
92/// ### Examples
93///
94/// ```
95/// use fp_library::{brands::*, functions::*};
96///
97/// let x = Some(5);
98/// let y = Some(10);
99/// let z = apply_second::<OptionBrand, _, _>(x, y);
100/// assert_eq!(z, Some(10));
101/// ```
102pub fn apply_second<'a, Brand: ApplySecond, A: 'a + Clone, B: 'a + Clone>(
103 fa: Apply!(<Brand as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
104 fb: Apply!(<Brand as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>),
105) -> Apply!(<Brand as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>) {
106 Brand::apply_second::<A, B>(fa, fb)
107}