1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
//! By-ref applicative functors, combining [`RefPointed`](crate::classes::RefPointed) and [`RefSemiapplicative`](crate::classes::RefSemiapplicative).
//!
//! This is the by-ref counterpart of [`Applicative`](crate::classes::Applicative).
//!
//! ### Examples
//!
//! ```
//! use fp_library::{
//! brands::*,
//! classes::*,
//! functions::*,
//! types::*,
//! };
//!
//! // ref_pure clones a value into a Lazy context
//! let x = ref_pure::<LazyBrand<RcLazyConfig>, _>(&42);
//! assert_eq!(*x.evaluate(), 42);
//!
//! // ref_apply applies a wrapped by-ref function
//! let f = RcLazy::pure(std::rc::Rc::new(|x: &i32| *x + 1) as std::rc::Rc<dyn Fn(&i32) -> i32>);
//! let result = ref_apply::<RcFnBrand, LazyBrand<RcLazyConfig>, _, _>(&f, &x);
//! assert_eq!(*result.evaluate(), 43);
//! ```
#[fp_macros::document_module]
mod inner {
use crate::classes::*;
/// A type class for by-ref applicative functors.
///
/// Combines [`RefPointed`] (injecting values from references) with
/// [`RefSemiapplicative`] (applying wrapped by-ref functions).
///
/// This is the by-ref counterpart of [`Applicative`]. Automatically
/// implemented for any type implementing both supertraits.
///
/// A lawful `RefApplicative` must satisfy the applicative laws
/// (identity, composition, homomorphism, interchange) expressed
/// in terms of `ref_pure` and `ref_apply`. These mirror the
/// standard [`Applicative`] laws but with by-ref function wrappers:
///
/// 1. **Identity**: `ref_apply(ref_pure(&id), v) = v` (evaluated values equal).
/// 2. **Homomorphism**: `ref_apply(ref_pure(&f), ref_pure(&x)) = ref_pure(&f(&x))`.
/// 3. **Interchange**: `ref_apply(u, ref_pure(&y)) = ref_apply(ref_pure(&(|f| f(&y))), u)`.
pub trait RefApplicative:
RefPointed + RefSemiapplicative + RefApplyFirst + RefApplySecond {
}
/// Blanket implementation of [`RefApplicative`].
#[document_type_parameters("The brand type.")]
impl<Brand> RefApplicative for Brand where
Brand: RefPointed + RefSemiapplicative + RefApplyFirst + RefApplySecond
{
}
}
pub use inner::*;