fp_library/v2/classes/
function.rs

1use crate::make_type_apply;
2use super::category::Category;
3use std::ops::Deref;
4
5/// Abstraction for wrappers over closures.
6///
7/// This trait is implemented by "Brand" types (like [`ArcFnBrand`][crate::brands::ArcFnBrand]
8/// and [`RcFnBrand`][crate::brands::RcFnBrand]) to provide a way to construct
9/// and type-check wrappers over closures (`Arc<dyn Fn...>`, `Rc<dyn Fn...>`,
10/// etc.) in a generic context, allowing library users to choose between
11/// implementations at function call sites.
12///
13/// The lifetime `'a` ensures the function doesn't outlive referenced data,
14/// while generic types `A` and `B` represent the input and output types, respectively.
15pub trait Function: Category {
16	type Output<'a, A, B>: Deref<Target = dyn 'a + Fn(A) -> B>;
17
18    /// Creates a new function wrapper.
19    ///
20    /// # Type Signature
21    ///
22    /// `forall a b. Function f => (a -> b) -> f a b`
23    ///
24    /// # Parameters
25    ///
26    /// * `f`: The closure to wrap.
27    ///
28    /// # Returns
29    ///
30    /// The wrapped function.
31    ///
32    /// # Examples
33    ///
34    /// ```
35    /// use fp_library::v2::classes::function::Function;
36    /// use fp_library::v2::types::rc_fn::RcFnBrand;
37    ///
38    /// let f = <RcFnBrand as Function>::new(|x: i32| x * 2);
39    /// assert_eq!(f(5), 10);
40    /// ```
41	fn new<'a, A, B>(f: impl 'a + Fn(A) -> B) -> ApplyFunction<'a, Self, A, B>;
42}
43
44make_type_apply!(ApplyFunction, Function, ('a), (A, B), "' -> * -> *");