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
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
//! By-reference indexed traversal of structures.
//!
//! ### Examples
//!
//! ```
//! use fp_library::{
//! brands::*,
//! functions::explicit::*,
//! };
//!
//! let v = vec![10, 20, 30];
//! let result: Option<Vec<String>> =
//! traverse_with_index::<RcFnBrand, VecBrand, _, _, OptionBrand, _, _>(
//! |i, x: &i32| Some(format!("{}:{}", i, x)),
//! &v,
//! );
//! assert_eq!(result, Some(vec!["0:10".to_string(), "1:20".to_string(), "2:30".to_string()]));
//! ```
#[fp_macros::document_module]
mod inner {
use {
crate::{
classes::*,
kinds::*,
},
fp_macros::*,
};
/// By-reference indexed traversal of structures.
///
/// Similar to [`TraversableWithIndex`], but the closure receives `&A`
/// instead of `A`. Combines indexed access with by-reference traversal.
#[kind(type Of<'a, A: 'a>: 'a;)]
pub trait RefTraversableWithIndex: RefTraversable + RefFunctorWithIndex + WithIndex {
/// Maps each element by reference with its index to a computation,
/// evaluates them, and combines the results.
#[document_signature]
///
#[document_type_parameters(
"The lifetime of the elements.",
"The type of the input elements.",
"The type of the output elements.",
"The applicative functor brand."
)]
///
#[document_parameters(
"The function to apply to each (index, element reference) pair.",
"The structure to traverse."
)]
///
#[document_returns("The combined result in the applicative context.")]
#[document_examples]
///
/// ```
/// use fp_library::{
/// brands::*,
/// functions::explicit::*,
/// };
///
/// let v = vec![10, 20, 30];
/// let result: Option<Vec<String>> =
/// traverse_with_index::<RcFnBrand, VecBrand, _, _, OptionBrand, _, _>(
/// |i, x: &i32| Some(format!("{}:{}", i, x)),
/// &v,
/// );
/// assert_eq!(result, Some(vec!["0:10".to_string(), "1:20".to_string(), "2:30".to_string()]));
/// ```
fn ref_traverse_with_index<'a, A: 'a + Clone, B: 'a + Clone, M: Applicative>(
f: impl Fn(Self::Index, &A) -> Apply!(<M as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>)
+ 'a,
ta: &Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
) -> Apply!(<M as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>)>)
where
Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>): Clone,
Apply!(<M as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>): Clone;
}
/// Maps each element by reference with its index to a computation,
/// evaluates them, and combines the results.
///
/// Free function version that dispatches to [the type class' associated function][`RefTraversableWithIndex::ref_traverse_with_index`].
#[document_signature]
///
#[document_type_parameters(
"The lifetime of the elements.",
"The brand of the structure.",
"The type of the input elements.",
"The type of the output elements.",
"The applicative functor brand."
)]
///
#[document_parameters(
"The function to apply to each (index, element reference) pair.",
"The structure to traverse."
)]
///
#[document_returns("The combined result in the applicative context.")]
#[document_examples]
///
/// ```
/// use fp_library::{
/// brands::*,
/// functions::explicit::*,
/// };
///
/// let v = vec![10, 20, 30];
/// let result: Option<Vec<String>> =
/// traverse_with_index::<RcFnBrand, VecBrand, _, _, OptionBrand, _, _>(
/// |i, x: &i32| Some(format!("{}:{}", i, x)),
/// &v,
/// );
/// assert_eq!(result, Some(vec!["0:10".to_string(), "1:20".to_string(), "2:30".to_string()]));
/// ```
pub fn ref_traverse_with_index<
'a,
Brand: RefTraversableWithIndex,
A: 'a + Clone,
B: 'a + Clone,
M: Applicative,
>(
f: impl Fn(Brand::Index, &A) -> Apply!(<M as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>) + 'a,
ta: &Apply!(<Brand as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
) -> Apply!(<M as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, Apply!(<Brand as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>)>)
where
Apply!(<Brand as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>): Clone,
Apply!(<M as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>): Clone, {
Brand::ref_traverse_with_index::<A, B, M>(f, ta)
}
}
pub use inner::*;