fp_library/typeclasses/
apply_first.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 first value.
7///
8/// `ApplyFirst` provides the ability to sequence two computations but discard
9/// the result of the second computation, keeping only the result of the first.
10/// This is useful for executing side effects in sequence while preserving the
11/// primary result.
12pub trait ApplyFirst: Kind0L1T {
13	/// Combines two contexts, keeping the value from the first context.
14	///
15	/// # Type Signature
16	///
17	/// `forall f a b. ApplyFirst f => f a -> f b -> f a`
18	///
19	/// # Parameters
20	///
21	/// * `fa`: The first context containing a value.
22	/// * `fb`: The second context containing a value (will be discarded).
23	///
24	/// # Returns
25	///
26	/// The first context with its value preserved.
27	fn apply_first<'a, ClonableFnBrand: 'a + ClonableFn, A: 'a + Clone, B>(
28		fa: Apply0L1T<Self, A>
29	) -> ApplyFn<'a, ClonableFnBrand, Apply0L1T<Self, B>, Apply0L1T<Self, A>>;
30}
31
32/// Combines two contexts, keeping the value from the first context.
33///
34/// Free function version that dispatches to [the typeclass' associated function][`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, RcFnBrand}, functions::apply_first};
53///
54/// assert_eq!(apply_first::<RcFnBrand, OptionBrand, _, _>(Some(5))(Some("hello")), Some(5));
55/// ```
56pub fn apply_first<'a, ClonableFnBrand: 'a + ClonableFn, Brand: ApplyFirst, A: 'a + Clone, B>(
57	fa: Apply0L1T<Brand, A>
58) -> ApplyFn<'a, ClonableFnBrand, Apply0L1T<Brand, B>, Apply0L1T<Brand, A>> {
59	Brand::apply_first::<ClonableFnBrand, A, B>(fa)
60}