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
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
//! Wrappers over closures for generic handling of functions in higher-kinded contexts.
//!
//! ### Examples
//!
//! ```
//! use fp_library::{
//! brands::*,
//! functions::*,
//! };
//!
//! let f = fn_new::<RcFnBrand, _, _>(|x: i32| x * 2);
//! assert_eq!(f(5), 10);
//! ```
#[fp_macros::document_module]
mod inner {
use {
crate::classes::{
profunctor::*,
*,
},
fp_macros::*,
std::ops::Deref,
};
/// A trait for wrappers over closures, allowing for generic handling of functions in higher-kinded contexts.
///
/// This trait is implemented by "Brand" types (like [`ArcFnBrand`][crate::brands::ArcFnBrand]
/// and [`RcFnBrand`][crate::brands::RcFnBrand]) to provide a way to construct
/// and type-check wrappers over closures (`Arc<dyn Fn...>`, `Rc<dyn Fn...>`,
/// etc.) in a generic context, allowing library users to choose between
/// implementations at function call sites.
///
/// The lifetime `'a` ensures the function doesn't outlive referenced data,
/// while generic types `A` and `B` represent the input and output types, respectively.
pub trait Function: Category + Strong {
/// The type of the function wrapper.
///
/// This associated type represents the concrete type of the wrapper (e.g., `Rc<dyn Fn(A) -> B>`)
/// that dereferences to the underlying closure.
type Of<'a, A: 'a, B: 'a>: Deref<Target = dyn 'a + Fn(A) -> B>;
/// Creates a new function wrapper.
///
/// This function wraps the provided closure `f` into a function wrapper.
#[document_signature]
///
#[document_type_parameters(
"The lifetime of the function and its captured data.",
"The input type of the function.",
"The output type of the function."
)]
///
#[document_parameters("The closure to wrap.", "The input value to the function.")]
#[document_returns("The wrapped function.")]
#[document_examples]
///
/// ```
/// use fp_library::{
/// brands::*,
/// functions::*,
/// };
///
/// let f = fn_new::<RcFnBrand, _, _>(|x: i32| x * 2);
/// assert_eq!(f(5), 10);
/// ```
fn new<'a, A: 'a, B: 'a>(f: impl 'a + Fn(A) -> B) -> <Self as Function>::Of<'a, A, B>;
}
/// Creates a new function wrapper.
///
/// Free function version that dispatches to [the type class' associated function][`Function::new`].
#[document_signature]
///
#[document_type_parameters(
"The lifetime of the function and its captured data.",
"The brand of the function wrapper.",
"The input type of the function.",
"The output type of the function."
)]
///
#[document_parameters("The closure to wrap.", "The input value to the function.")]
#[document_returns("The wrapped function.")]
#[document_examples]
///
/// ```
/// use fp_library::{
/// brands::*,
/// functions::*,
/// };
///
/// let f = fn_new::<RcFnBrand, _, _>(|x: i32| x * 2);
/// assert_eq!(f(5), 10);
/// ```
pub fn new<'a, Brand, A, B>(f: impl 'a + Fn(A) -> B) -> <Brand as Function>::Of<'a, A, B>
where
Brand: Function, {
Brand::new(f)
}
}
pub use inner::*;