fp_library/typeclasses/
apply_second.rs

1use crate::{
2	aliases::ArcFn,
3	hkt::{Apply1, Kind1},
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: Kind1 {
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, A: 'a, B: 'a + Clone>(
28		fa: Apply1<Self, A>
29	) -> ArcFn<'a, Apply1<Self, B>, Apply1<Self, B>>
30	where
31		Apply1<Self, A>: Clone;
32}
33
34/// Combines two contexts, keeping the value from the second context.
35///
36/// Free function version that dispatches to [the typeclass' associated function][`ApplySecond::apply_second`].
37///
38/// # Type Signature
39///
40/// `forall f a b. ApplySecond f => f a -> f b -> f b`
41///
42/// # Parameters
43///
44/// * `fa`: The first context containing a value (will be discarded).
45/// * `fb`: The second context containing a value.
46///
47/// # Returns
48///
49/// The second context with its value preserved.
50///
51/// # Examples
52///
53/// ```
54/// use fp_library::{brands::OptionBrand, functions::apply_second};
55///
56/// assert_eq!(apply_second::<OptionBrand, _, _>(Some(5))(Some("hello")), Some("hello"));
57/// ```
58pub fn apply_second<'a, Brand: ApplySecond, A: 'a, B: 'a + Clone>(
59	fa: Apply1<Brand, A>
60) -> ArcFn<'a, Apply1<Brand, B>, Apply1<Brand, B>>
61where
62	Apply1<Brand, A>: Clone,
63{
64	Brand::apply_second::<A, B>(fa)
65}