Skip to main content

fp_library/classes/
ref_apply_second.rs

1//! Combining two by-ref contexts, keeping the second value, with [`ref_apply_second`].
2//!
3//! This is the by-ref counterpart of [`ApplySecond`](crate::classes::ApplySecond).
4//!
5//! ### Examples
6//!
7//! ```
8//! use fp_library::{
9//! 	brands::*,
10//! 	functions::{
11//! 		explicit::apply_second,
12//! 		*,
13//! 	},
14//! 	types::*,
15//! };
16//!
17//! let x = RcLazy::pure(3);
18//! let y = RcLazy::pure(4);
19//! let result = apply_second::<LazyBrand<RcLazyConfig>, _, _, _, _>(&x, &y);
20//! assert_eq!(*result.evaluate(), 4);
21//! ```
22
23#[fp_macros::document_module]
24mod inner {
25	use {
26		crate::kinds::*,
27		fp_macros::*,
28	};
29
30	/// A type class for combining two by-ref contexts, keeping the second value.
31	///
32	/// Requires `B: Clone` because the closure receives `&B` and must produce
33	/// an owned `B`. The default implementation uses [`RefLift::ref_lift2`](crate::classes::RefLift::ref_lift2).
34	#[kind(type Of<'a, A: 'a>: 'a;)]
35	pub trait RefApplySecond: crate::classes::RefLift {
36		/// Combines two contexts, keeping the value from the second.
37		#[document_signature]
38		///
39		#[document_type_parameters(
40			"The lifetime of the values.",
41			"The type of the value in the first context.",
42			"The type of the value in the second context. Must be `Clone`."
43		)]
44		///
45		#[document_parameters("The first context.", "The second context.")]
46		///
47		#[document_returns("A new context containing the value from the second context.")]
48		#[document_examples]
49		///
50		/// ```
51		/// use fp_library::{
52		/// 	brands::*,
53		/// 	classes::*,
54		/// 	types::*,
55		/// };
56		///
57		/// let x = RcLazy::pure(3);
58		/// let y = RcLazy::pure(4);
59		/// let result = LazyBrand::<RcLazyConfig>::ref_apply_second(&x, &y);
60		/// assert_eq!(*result.evaluate(), 4);
61		/// ```
62		fn ref_apply_second<'a, A: 'a, B: Clone + 'a>(
63			fa: &Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
64			fb: &Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>),
65		) -> Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>) {
66			Self::ref_lift2(|_: &A, b: &B| b.clone(), fa, fb)
67		}
68	}
69
70	/// Blanket implementation of [`RefApplySecond`].
71	#[document_type_parameters("The brand type.")]
72	impl<Brand: crate::classes::RefLift> RefApplySecond for Brand {}
73
74	/// Combines two contexts, keeping the value from the second.
75	///
76	/// Free function version that dispatches to [the type class' associated function][`RefApplySecond::ref_apply_second`].
77	#[document_signature]
78	///
79	#[document_type_parameters(
80		"The lifetime of the values.",
81		"The brand of the context.",
82		"The type of the value in the first context.",
83		"The type of the value in the second context. Must be `Clone`."
84	)]
85	///
86	#[document_parameters("The first context.", "The second context.")]
87	///
88	#[document_returns("A new context containing the value from the second context.")]
89	#[document_examples]
90	///
91	/// ```
92	/// use fp_library::{
93	/// 	brands::*,
94	/// 	functions::{
95	/// 		explicit::apply_second,
96	/// 		*,
97	/// 	},
98	/// 	types::*,
99	/// };
100	///
101	/// let x = RcLazy::pure(3);
102	/// let y = RcLazy::pure(4);
103	/// let result = apply_second::<LazyBrand<RcLazyConfig>, _, _, _, _>(&x, &y);
104	/// assert_eq!(*result.evaluate(), 4);
105	/// ```
106	pub fn ref_apply_second<'a, Brand: RefApplySecond, A: 'a, B: Clone + 'a>(
107		fa: &Apply!(<Brand as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
108		fb: &Apply!(<Brand as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>),
109	) -> Apply!(<Brand as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>) {
110		Brand::ref_apply_second(fa, fb)
111	}
112}
113
114pub use inner::*;