fp_library/typeclasses/
apply_second.rs

1use crate::{
2	hkt::{Apply0L1T, Kind0L1T},
3	typeclasses::{ClonableFn, clonable_fn::ApplyFn},
4};
5
6/// A typeclass for types that support combining two contexts, keeping the second value.
7///
8/// `ApplySecond` provides the ability to sequence two computations but discard
9/// the result of the first computation, keeping only the result of the second.
10/// This is useful for executing side effects in sequence while preserving the
11/// final result.
12pub trait ApplySecond: Kind0L1T {
13	/// Combines two contexts, keeping the value from the second context.
14	///
15	/// # Type Signature
16	///
17	/// `forall f a b. ApplySecond f => f a -> f b -> f b`
18	///
19	/// # Parameters
20	///
21	/// * `fa`: The first context containing a value (will be discarded).
22	/// * `fb`: The second context containing a value.
23	///
24	/// # Returns
25	///
26	/// The second context with its value preserved.
27	fn apply_second<'a, ClonableFnBrand: 'a + ClonableFn, A: 'a + Clone, B: 'a + Clone>(
28		fa: Apply0L1T<Self, A>
29	) -> ApplyFn<'a, ClonableFnBrand, Apply0L1T<Self, B>, Apply0L1T<Self, B>>;
30}
31
32/// Combines two contexts, keeping the value from the second context.
33///
34/// Free function version that dispatches to [the typeclass' associated function][`ApplySecond::apply_second`].
35///
36/// # Type Signature
37///
38/// `forall f a b. ApplySecond f => f a -> f b -> f b`
39///
40/// # Parameters
41///
42/// * `fa`: The first context containing a value (will be discarded).
43/// * `fb`: The second context containing a value.
44///
45/// # Returns
46///
47/// The second context with its value preserved.
48///
49/// # Examples
50///
51/// ```
52/// use fp_library::{brands::{OptionBrand, RcFnBrand}, functions::apply_second};
53///
54/// assert_eq!(apply_second::<RcFnBrand, OptionBrand, _, _>(Some(5))(Some("hello")), Some("hello"));
55/// ```
56pub fn apply_second<
57	'a,
58	ClonableFnBrand: 'a + ClonableFn,
59	Brand: ApplySecond,
60	A: 'a + Clone,
61	B: 'a + Clone,
62>(
63	fa: Apply0L1T<Brand, A>
64) -> ApplyFn<'a, ClonableFnBrand, Apply0L1T<Brand, B>, Apply0L1T<Brand, B>> {
65	Brand::apply_second::<ClonableFnBrand, A, B>(fa)
66}