fp_library/typeclasses/
apply_first.rs

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