1#[fp_macros::document_module]
6mod inner {
7 use {
8 crate::{
9 Apply,
10 brands::optics::*,
11 classes::{
12 CloneableFn,
13 profunctor::{
14 Closed,
15 Profunctor,
16 },
17 },
18 impl_kind,
19 kinds::*,
20 },
21 fp_macros::*,
22 };
23
24 #[document_type_parameters(
26 "The lifetime of the functions.",
27 "The cloneable function brand.",
28 "The type of the value produced by the inner function.",
29 "The type of the value consumed by the inner function.",
30 "The source type of the structure.",
31 "The target type of the structure."
32 )]
33 pub struct Grating<'a, FunctionBrand: CloneableFn, A: 'a, B: 'a, S: 'a, T: 'a> {
34 pub run: <FunctionBrand as CloneableFn>::Of<
36 'a,
37 <FunctionBrand as CloneableFn>::Of<'a, <FunctionBrand as CloneableFn>::Of<'a, S, A>, B>,
38 T,
39 >,
40 }
41
42 #[document_type_parameters(
43 "The lifetime of the functions.",
44 "The cloneable function brand.",
45 "The type of the value produced by the inner function.",
46 "The type of the value consumed by the inner function.",
47 "The source type of the structure.",
48 "The target type of the structure."
49 )]
50 impl<'a, FunctionBrand: CloneableFn, A: 'a, B: 'a, S: 'a, T: 'a>
51 Grating<'a, FunctionBrand, A, B, S, T>
52 {
53 #[document_signature]
55 #[document_parameters("The grating function.")]
57 #[document_returns("A new instance of the type.")]
59 #[document_examples]
61 pub fn new(
83 run: <FunctionBrand as CloneableFn>::Of<
84 'a,
85 <FunctionBrand as CloneableFn>::Of<
86 'a,
87 <FunctionBrand as CloneableFn>::Of<'a, S, A>,
88 B,
89 >,
90 T,
91 >
92 ) -> Self {
93 Grating {
94 run,
95 }
96 }
97 }
98
99 impl_kind! {
100 impl<FunctionBrand: CloneableFn + 'static, A: 'static, B: 'static> for GratingBrand<FunctionBrand, A, B> {
101 #[document_default]
102 type Of<'a, S: 'a, T: 'a>: 'a = Grating<'a, FunctionBrand, A, B, S, T>;
103 }
104 }
105
106 #[document_type_parameters(
107 "The cloneable function brand.",
108 "The type of the value produced by the inner function.",
109 "The type of the value consumed by the inner function."
110 )]
111 impl<FunctionBrand: CloneableFn + 'static, A: 'static, B: 'static> Profunctor
112 for GratingBrand<FunctionBrand, A, B>
113 {
114 #[document_signature]
116 #[document_type_parameters(
118 "The lifetime of the functions.",
119 "The source type of the new structure.",
120 "The target type of the new structure.",
121 "The source type of the original structure.",
122 "The target type of the original structure."
123 )]
124 #[document_parameters(
126 "The function to apply to the input.",
127 "The function to apply to the output.",
128 "The grating instance to transform."
129 )]
130 #[document_returns("A transformed `Grating` instance.")]
132 #[document_examples]
134 fn dimap<'a, S: 'a, T: 'a, U: 'a, V: 'a>(
169 st: impl Fn(S) -> T + 'a,
170 uv: impl Fn(U) -> V + 'a,
171 puv: Apply!(<Self as Kind!( type Of<'a, T: 'a, U: 'a>: 'a; )>::Of<'a, T, U>),
172 ) -> Apply!(<Self as Kind!( type Of<'a, T: 'a, U: 'a>: 'a; )>::Of<'a, S, V>) {
173 let run = puv.run;
174 let st = <FunctionBrand as CloneableFn>::new(st);
175 let uv = <FunctionBrand as CloneableFn>::new(uv);
176 Grating::<FunctionBrand, A, B, S, V>::new(<FunctionBrand as CloneableFn>::new(
177 move |f: <FunctionBrand as CloneableFn>::Of<
178 'a,
179 <FunctionBrand as CloneableFn>::Of<'a, S, A>,
180 B,
181 >| {
182 let st = st.clone();
183 let uv = uv.clone();
184 (*uv)((*run)(<FunctionBrand as CloneableFn>::new(
185 move |g: <FunctionBrand as CloneableFn>::Of<'a, T, A>| {
186 let st = st.clone();
187 f(<FunctionBrand as CloneableFn>::new(move |s| g((*st)(s))))
188 },
189 )))
190 },
191 ))
192 }
193 }
194
195 #[document_type_parameters(
196 "The cloneable function brand.",
197 "The type of the value produced by the inner function.",
198 "The type of the value consumed by the inner function."
199 )]
200 impl<FunctionBrand: CloneableFn + 'static, A: 'static, B: 'static> Closed<FunctionBrand>
201 for GratingBrand<FunctionBrand, A, B>
202 {
203 #[document_signature]
205 #[document_type_parameters(
207 "The lifetime of the functions.",
208 "The source type of the structure.",
209 "The target type of the structure.",
210 "The type of the function input."
211 )]
212 #[document_parameters("The grating instance to transform.")]
214 #[document_returns("A transformed `Grating` instance that operates on functions.")]
216 #[document_examples]
218 fn closed<'a, S: 'a, T: 'a, X: 'a + Clone>(
260 pab: Apply!(<Self as Kind!( type Of<'a, T: 'a, U: 'a>: 'a; )>::Of<'a, S, T>)
261 ) -> Apply!(<Self as Kind!( type Of<'a, T: 'a, U: 'a>: 'a; )>::Of<'a, <FunctionBrand as CloneableFn>::Of<'a, X, S>, <FunctionBrand as CloneableFn>::Of<'a, X, T>>)
262 {
263 let run = pab.run;
264 Grating::<
265 FunctionBrand,
266 A,
267 B,
268 <FunctionBrand as CloneableFn>::Of<'a, X, S>,
269 <FunctionBrand as CloneableFn>::Of<'a, X, T>,
270 >::new(<FunctionBrand as CloneableFn>::new(
271 move |g: <FunctionBrand as CloneableFn>::Of<
272 'a,
273 <FunctionBrand as CloneableFn>::Of<
274 'a,
275 <FunctionBrand as CloneableFn>::Of<'a, X, S>,
276 A,
277 >,
278 B,
279 >| {
280 let run = run.clone();
281 <FunctionBrand as CloneableFn>::new(move |x: X| {
282 let g = g.clone();
283 let x = x.clone();
284 (*run)(<FunctionBrand as CloneableFn>::new(
285 move |h: <FunctionBrand as CloneableFn>::Of<'a, S, A>| {
286 let x = x.clone();
287 g(<FunctionBrand as CloneableFn>::new(
288 move |k: <FunctionBrand as CloneableFn>::Of<'a, X, S>| {
289 h(k(x.clone()))
290 },
291 ))
292 },
293 ))
294 })
295 },
296 ))
297 }
298 }
299}
300pub use inner::*;