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}