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), "' -> * -> *");