Skip to main content

fp_library/types/optics/
composed.rs

1//! The `Composed` struct for composing optics.
2
3use {
4	crate::{
5		Apply,
6		brands::{
7			FnBrand,
8			optics::*,
9		},
10		classes::{
11			CloneableFn,
12			UnsizedCoercible,
13			monoid::Monoid,
14			optics::*,
15			profunctor::{
16				Choice,
17				Closed,
18				Profunctor,
19				Strong,
20				Wander,
21			},
22		},
23		kinds::*,
24	},
25	fp_macros::*,
26	std::marker::PhantomData,
27};
28
29#[fp_macros::document_module]
30mod inner {
31	use super::*;
32
33	/// This struct represents the composition of two optics, allowing them to be
34	/// combined into a single optic that applies both transformations.
35	#[document_type_parameters(
36		"The lifetime of the values.",
37		"The source type of the outer structure.",
38		"The target type of the outer structure.",
39		"The source type of the intermediate structure.",
40		"The target type of the intermediate structure.",
41		"The source type of the focus.",
42		"The target type of the focus.",
43		"The first optic.",
44		"The second optic."
45	)]
46	#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash)]
47	pub struct Composed<'a, S, T, M, N, A, B, O1, O2> {
48		/// The outer optic (applied second).
49		pub first: O1,
50		/// The inner optic (applied first).
51		pub second: O2,
52		pub(crate) _phantom: PhantomData<&'a (S, T, M, N, A, B)>,
53	}
54
55	#[document_type_parameters(
56		"The lifetime of the values.",
57		"The source type of the outer structure.",
58		"The target type of the outer structure.",
59		"The source type of the intermediate structure.",
60		"The target type of the intermediate structure.",
61		"The source type of the focus.",
62		"The target type of the focus.",
63		"The first optic.",
64		"The second optic."
65	)]
66	impl<'a, S, T, M, N, A, B, O1, O2> Composed<'a, S, T, M, N, A, B, O1, O2> {
67		/// Create a new composed optic.
68		#[document_signature]
69		///
70		#[document_parameters(
71			"The outer optic (applied second).",
72			"The inner optic (applied first)."
73		)]
74		///
75		#[document_returns("A new instance of the type.")]
76		#[document_examples]
77		///
78		/// ```
79		/// use fp_library::{
80		/// 	brands::{
81		/// 		optics::*,
82		/// 		*,
83		/// 	},
84		/// 	classes::optics::*,
85		/// 	functions::*,
86		/// 	types::optics::*,
87		/// };
88		///
89		/// let l1: LensPrime<RcBrand, (i32, String), i32> =
90		/// 	LensPrime::from_view_set(|(x, _): (i32, String)| x, |((_, s), x)| (x, s));
91		/// let l2: LensPrime<RcBrand, i32, i32> = LensPrime::from_view_set(|x: i32| x, |(_, x)| x);
92		/// let composed = Composed::new(l1, l2);
93		///
94		/// let f = cloneable_fn_new::<RcFnBrand, _, _>(|x: i32| x * 2);
95		/// let modifier = <Composed<
96		/// 	'_,
97		/// 	(i32, String),
98		/// 	(i32, String),
99		/// 	i32,
100		/// 	i32,
101		/// 	i32,
102		/// 	i32,
103		/// 	LensPrime<RcBrand, (i32, String), i32>,
104		/// 	LensPrime<RcBrand, i32, i32>,
105		/// > as Optic<RcFnBrand, _, _, _, _>>::evaluate(&composed, f);
106		/// assert_eq!(modifier((21, "hi".to_string())), (42, "hi".to_string()));
107		/// ```
108		pub fn new(
109			first: O1,
110			second: O2,
111		) -> Self {
112			Composed {
113				first,
114				second,
115				_phantom: PhantomData,
116			}
117		}
118	}
119
120	#[document_type_parameters(
121		"The lifetime of the values.",
122		"The profunctor type.",
123		"The source type of the outer structure.",
124		"The target type of the outer structure.",
125		"The source type of the intermediate structure.",
126		"The target type of the intermediate structure.",
127		"The source type of the focus.",
128		"The target type of the focus.",
129		"The first optic.",
130		"The second optic."
131	)]
132	#[document_parameters("The composed optic instance.")]
133	impl<'a, P, S: 'a, T: 'a, M: 'a, N: 'a, A: 'a, B: 'a, O1, O2> Optic<'a, P, S, T, A, B>
134		for Composed<'a, S, T, M, N, A, B, O1, O2>
135	where
136		P: Profunctor,
137		O1: Optic<'a, P, S, T, M, N>,
138		O2: Optic<'a, P, M, N, A, B>,
139	{
140		#[document_signature]
141		#[document_parameters("The profunctor value to transform.")]
142		#[document_returns("The transformed profunctor value.")]
143		#[document_examples]
144		///
145		/// ```
146		/// use fp_library::{
147		/// 	brands::{
148		/// 		optics::*,
149		/// 		*,
150		/// 	},
151		/// 	classes::optics::*,
152		/// 	functions::*,
153		/// 	types::optics::*,
154		/// };
155		///
156		/// let l1: LensPrime<RcBrand, (i32, String), i32> =
157		/// 	LensPrime::from_view_set(|(x, _): (i32, String)| x, |((_, s), x)| (x, s));
158		/// let l2: LensPrime<RcBrand, i32, i32> = LensPrime::from_view_set(|x: i32| x, |(_, x)| x);
159		/// let composed = Composed::new(l1, l2);
160		///
161		/// let f = cloneable_fn_new::<RcFnBrand, _, _>(|x: i32| x * 2);
162		/// let modifier = <Composed<
163		/// 	'_,
164		/// 	(i32, String),
165		/// 	(i32, String),
166		/// 	i32,
167		/// 	i32,
168		/// 	i32,
169		/// 	i32,
170		/// 	LensPrime<RcBrand, (i32, String), i32>,
171		/// 	LensPrime<RcBrand, i32, i32>,
172		/// > as Optic<RcFnBrand, _, _, _, _>>::evaluate(&composed, f);
173		/// assert_eq!(modifier((21, "hi".to_string())), (42, "hi".to_string()));
174		/// ```
175		fn evaluate(
176			&self,
177			pab: Apply!(<P as Kind!( type Of<'b, T: 'b, U: 'b>: 'b; )>::Of<'a, A, B>),
178		) -> Apply!(<P as Kind!( type Of<'b, T: 'b, U: 'b>: 'b; )>::Of<'a, S, T>) {
179			let pmn = self.second.evaluate(pab);
180			self.first.evaluate(pmn)
181		}
182	}
183
184	#[document_type_parameters(
185		"The lifetime of the values.",
186		"The source type of the outer structure.",
187		"The target type of the outer structure.",
188		"The source type of the intermediate structure.",
189		"The target type of the intermediate structure.",
190		"The source type of the focus.",
191		"The target type of the focus.",
192		"The first optic.",
193		"The second optic."
194	)]
195	#[document_parameters("The composed optic instance.")]
196	impl<'a, S, T, M, N, A, B, O1, O2> IsoOptic<'a, S, T, A, B>
197		for Composed<'a, S, T, M, N, A, B, O1, O2>
198	where
199		O1: IsoOptic<'a, S, T, M, N>,
200		O2: IsoOptic<'a, M, N, A, B>,
201	{
202		#[document_signature]
203		#[document_type_parameters("The profunctor type.")]
204		#[document_parameters("The profunctor value to transform.")]
205		#[document_returns("The transformed profunctor value.")]
206		#[document_examples]
207		///
208		/// ```
209		/// use fp_library::{
210		/// 	brands::{
211		/// 		optics::*,
212		/// 		*,
213		/// 	},
214		/// 	classes::optics::*,
215		/// 	functions::*,
216		/// 	types::optics::*,
217		/// };
218		///
219		/// let iso1: IsoPrime<RcBrand, i32, i32> = IsoPrime::new(|x| x, |x| x);
220		/// let iso2: IsoPrime<RcBrand, i32, i32> = IsoPrime::new(|x| x, |x| x);
221		/// let composed = Composed::new(iso1, iso2);
222		/// let f = cloneable_fn_new::<RcFnBrand, _, _>(|x: i32| x * 2);
223		/// let modifier = <Composed<
224		/// 	'_,
225		/// 	i32,
226		/// 	i32,
227		/// 	i32,
228		/// 	i32,
229		/// 	i32,
230		/// 	i32,
231		/// 	IsoPrime<RcBrand, i32, i32>,
232		/// 	IsoPrime<RcBrand, i32, i32>,
233		/// > as IsoOptic<i32, i32, i32, i32>>::evaluate::<RcFnBrand>(&composed, f);
234		/// assert_eq!(modifier(21), 42);
235		/// ```
236		fn evaluate<P: Profunctor + 'static>(
237			&self,
238			pab: Apply!(<P as Kind!( type Of<'b, T: 'b, U: 'b>: 'b; )>::Of<'a, A, B>),
239		) -> Apply!(<P as Kind!( type Of<'b, T: 'b, U: 'b>: 'b; )>::Of<'a, S, T>) {
240			let pmn = IsoOptic::evaluate::<P>(&self.second, pab);
241			IsoOptic::evaluate::<P>(&self.first, pmn)
242		}
243	}
244
245	#[document_type_parameters(
246		"The lifetime of the values.",
247		"The source type of the outer structure.",
248		"The target type of the outer structure.",
249		"The source type of the intermediate structure.",
250		"The target type of the intermediate structure.",
251		"The source type of the focus.",
252		"The target type of the focus.",
253		"The first optic.",
254		"The second optic."
255	)]
256	#[document_parameters("The composed optic instance.")]
257	impl<'a, S, T, M, N, A, B, O1, O2> LensOptic<'a, S, T, A, B>
258		for Composed<'a, S, T, M, N, A, B, O1, O2>
259	where
260		O1: LensOptic<'a, S, T, M, N>,
261		O2: LensOptic<'a, M, N, A, B>,
262	{
263		#[document_signature]
264		#[document_type_parameters("The profunctor type.")]
265		#[document_parameters("The profunctor value to transform.")]
266		#[document_returns("The transformed profunctor value.")]
267		#[document_examples]
268		///
269		/// ```
270		/// use fp_library::{
271		/// 	brands::{
272		/// 		optics::*,
273		/// 		*,
274		/// 	},
275		/// 	classes::optics::*,
276		/// 	functions::*,
277		/// 	types::optics::*,
278		/// };
279		///
280		/// let l1: LensPrime<RcBrand, (i32, String), i32> =
281		/// 	LensPrime::from_view_set(|(x, _)| x, |((_, s), x)| (x, s));
282		/// let l2: LensPrime<RcBrand, i32, i32> = LensPrime::from_view_set(|x| x, |(_, x)| x);
283		/// let composed = Composed::new(l1, l2);
284		/// let f = cloneable_fn_new::<RcFnBrand, _, _>(|x: i32| x * 2);
285		/// let modifier = <Composed<
286		/// 	'_,
287		/// 	(i32, String),
288		/// 	(i32, String),
289		/// 	i32,
290		/// 	i32,
291		/// 	i32,
292		/// 	i32,
293		/// 	LensPrime<RcBrand, (i32, String), i32>,
294		/// 	LensPrime<RcBrand, i32, i32>,
295		/// > as LensOptic<(i32, String), (i32, String), i32, i32>>::evaluate::<RcFnBrand>(
296		/// 	&composed, f
297		/// );
298		/// assert_eq!(modifier((21, "hi".to_string())), (42, "hi".to_string()));
299		/// ```
300		fn evaluate<P: Strong>(
301			&self,
302			pab: Apply!(<P as Kind!( type Of<'b, T: 'b, U: 'b>: 'b; )>::Of<'a, A, B>),
303		) -> Apply!(<P as Kind!( type Of<'b, T: 'b, U: 'b>: 'b; )>::Of<'a, S, T>) {
304			let pmn = LensOptic::evaluate::<P>(&self.second, pab);
305			LensOptic::evaluate::<P>(&self.first, pmn)
306		}
307	}
308
309	#[document_type_parameters(
310		"The lifetime of the values.",
311		"The source type of the outer structure.",
312		"The target type of the outer structure.",
313		"The source type of the intermediate structure.",
314		"The target type of the intermediate structure.",
315		"The source type of the focus.",
316		"The target type of the focus.",
317		"The first optic.",
318		"The second optic."
319	)]
320	#[document_parameters("The composed optic instance.")]
321	impl<'a, S, T, M, N, A, B, O1, O2> PrismOptic<'a, S, T, A, B>
322		for Composed<'a, S, T, M, N, A, B, O1, O2>
323	where
324		O1: PrismOptic<'a, S, T, M, N>,
325		O2: PrismOptic<'a, M, N, A, B>,
326	{
327		#[document_signature]
328		#[document_type_parameters("The profunctor type.")]
329		#[document_parameters("The profunctor value to transform.")]
330		#[document_returns("The transformed profunctor value.")]
331		#[document_examples]
332		///
333		/// ```
334		/// use fp_library::{
335		/// 	brands::{
336		/// 		optics::*,
337		/// 		*,
338		/// 	},
339		/// 	classes::optics::*,
340		/// 	functions::*,
341		/// 	types::optics::*,
342		/// };
343		///
344		/// let p1: PrismPrime<RcBrand, Option<i32>, i32> = PrismPrime::from_option(|o| o, Some);
345		/// let p2: PrismPrime<RcBrand, i32, i32> = PrismPrime::from_option(Some, |x| x);
346		/// let composed = Composed::new(p1, p2);
347		/// let f = cloneable_fn_new::<RcFnBrand, _, _>(|x: i32| x * 2);
348		/// let modifier =
349		/// 	<Composed<
350		/// 		'_,
351		/// 		Option<i32>,
352		/// 		Option<i32>,
353		/// 		i32,
354		/// 		i32,
355		/// 		i32,
356		/// 		i32,
357		/// 		PrismPrime<RcBrand, Option<i32>, i32>,
358		/// 		PrismPrime<RcBrand, i32, i32>,
359		/// 	> as PrismOptic<Option<i32>, Option<i32>, i32, i32>>::evaluate::<RcFnBrand>(&composed, f);
360		/// assert_eq!(modifier(Some(21)), Some(42));
361		/// ```
362		fn evaluate<P: Choice>(
363			&self,
364			pab: Apply!(<P as Kind!( type Of<'b, T: 'b, U: 'b>: 'b; )>::Of<'a, A, B>),
365		) -> Apply!(<P as Kind!( type Of<'b, T: 'b, U: 'b>: 'b; )>::Of<'a, S, T>) {
366			let pmn = PrismOptic::evaluate::<P>(&self.second, pab);
367			PrismOptic::evaluate::<P>(&self.first, pmn)
368		}
369	}
370
371	#[document_type_parameters(
372		"The lifetime of the values.",
373		"The source type of the outer structure.",
374		"The target type of the outer structure.",
375		"The source type of the intermediate structure.",
376		"The target type of the intermediate structure.",
377		"The source type of the focus.",
378		"The target type of the focus.",
379		"The first optic.",
380		"The second optic."
381	)]
382	#[document_parameters("The composed optic instance.")]
383	impl<'a, S, T, M, N, A, B, O1, O2> AffineTraversalOptic<'a, S, T, A, B>
384		for Composed<'a, S, T, M, N, A, B, O1, O2>
385	where
386		O1: AffineTraversalOptic<'a, S, T, M, N>,
387		O2: AffineTraversalOptic<'a, M, N, A, B>,
388	{
389		#[document_signature]
390		#[document_type_parameters("The profunctor type.")]
391		#[document_parameters("The profunctor value to transform.")]
392		#[document_returns("The transformed profunctor value.")]
393		#[document_examples]
394		///
395		/// ```
396		/// use fp_library::{
397		/// 	brands::{
398		/// 		optics::*,
399		/// 		*,
400		/// 	},
401		/// 	classes::optics::*,
402		/// 	functions::*,
403		/// 	types::optics::*,
404		/// };
405		///
406		/// let l1: LensPrime<RcBrand, (i32, String), i32> =
407		/// 	LensPrime::from_view_set(|(x, _): (i32, String)| x, |((_, s), x)| (x, s));
408		/// let p2: PrismPrime<RcBrand, i32, i32> = PrismPrime::from_option(Some, |x| x);
409		/// let composed = Composed::new(l1, p2);
410		///
411		/// let f = cloneable_fn_new::<RcFnBrand, _, _>(|x: i32| x * 2);
412		/// let modifier = <Composed<
413		/// 	'_,
414		/// 	(i32, String),
415		/// 	(i32, String),
416		/// 	i32,
417		/// 	i32,
418		/// 	i32,
419		/// 	i32,
420		/// 	LensPrime<RcBrand, (i32, String), i32>,
421		/// 	PrismPrime<RcBrand, i32, i32>,
422		/// > as AffineTraversalOptic<(i32, String), (i32, String), i32, i32>>::evaluate::<RcFnBrand>(
423		/// 	&composed, f,
424		/// );
425		/// assert_eq!(modifier((21, "hi".to_string())), (42, "hi".to_string()));
426		/// ```
427		fn evaluate<P: Strong + Choice>(
428			&self,
429			pab: Apply!(<P as Kind!( type Of<'b, T: 'b, U: 'b>: 'b; )>::Of<'a, A, B>),
430		) -> Apply!(<P as Kind!( type Of<'b, T: 'b, U: 'b>: 'b; )>::Of<'a, S, T>) {
431			let pmn = AffineTraversalOptic::evaluate::<P>(&self.second, pab);
432			AffineTraversalOptic::evaluate::<P>(&self.first, pmn)
433		}
434	}
435
436	#[document_type_parameters(
437		"The lifetime of the values.",
438		"The source type of the outer structure.",
439		"The target type of the outer structure.",
440		"The source type of the intermediate structure.",
441		"The target type of the intermediate structure.",
442		"The source type of the focus.",
443		"The target type of the focus.",
444		"The first optic.",
445		"The second optic."
446	)]
447	#[document_parameters("The composed optic instance.")]
448	impl<'a, S, T, M, N, A, B, O1, O2> TraversalOptic<'a, S, T, A, B>
449		for Composed<'a, S, T, M, N, A, B, O1, O2>
450	where
451		O1: TraversalOptic<'a, S, T, M, N>,
452		O2: TraversalOptic<'a, M, N, A, B>,
453	{
454		#[document_signature]
455		#[document_type_parameters("The profunctor type.")]
456		#[document_parameters("The profunctor value to transform.")]
457		#[document_returns("The transformed profunctor value.")]
458		#[document_examples]
459		///
460		/// ```
461		/// use fp_library::{
462		/// 	brands::{
463		/// 		optics::*,
464		/// 		*,
465		/// 	},
466		/// 	classes::optics::*,
467		/// 	functions::*,
468		/// 	types::optics::*,
469		/// };
470		///
471		/// // Composition combines two optics
472		/// let l1: LensPrime<RcBrand, (i32, String), i32> =
473		/// 	LensPrime::from_view_set(|(x, _)| x, |((_, s), x)| (x, s));
474		/// let l2: LensPrime<RcBrand, i32, i32> = LensPrime::from_view_set(|x| x, |(_, x)| x);
475		/// let composed = Composed::new(l1, l2);
476		/// let f = cloneable_fn_new::<RcFnBrand, _, _>(|x: i32| x * 2);
477		/// let modifier = <Composed<
478		/// 	'_,
479		/// 	(i32, String),
480		/// 	(i32, String),
481		/// 	i32,
482		/// 	i32,
483		/// 	i32,
484		/// 	i32,
485		/// 	LensPrime<RcBrand, (i32, String), i32>,
486		/// 	LensPrime<RcBrand, i32, i32>,
487		/// > as Optic<RcFnBrand, _, _, _, _>>::evaluate(&composed, f);
488		/// assert_eq!(modifier((21, "hi".to_string())), (42, "hi".to_string()));
489		/// ```
490		fn evaluate<P: Wander>(
491			&self,
492			pab: Apply!(<P as Kind!( type Of<'b, T: 'b, U: 'b>: 'b; )>::Of<'a, A, B>),
493		) -> Apply!(<P as Kind!( type Of<'b, T: 'b, U: 'b>: 'b; )>::Of<'a, S, T>) {
494			let pmn = TraversalOptic::evaluate::<P>(&self.second, pab);
495			TraversalOptic::evaluate::<P>(&self.first, pmn)
496		}
497	}
498
499	#[document_type_parameters(
500		"The lifetime of the values.",
501		"The source type of the structure.",
502		"The focus type.",
503		"The intermediate type.",
504		"The first optic.",
505		"The second optic."
506	)]
507	#[document_parameters("The composed optic instance.")]
508	impl<'a, S, A, M, O1, O2> GetterOptic<'a, S, A> for Composed<'a, S, S, M, M, A, A, O1, O2>
509	where
510		O1: GetterOptic<'a, S, M>,
511		O2: GetterOptic<'a, M, A>,
512		M: 'a,
513		A: 'a,
514	{
515		#[document_signature]
516		#[document_type_parameters(
517			"The return type of the forget profunctor.",
518			"The reference-counted pointer type."
519		)]
520		#[document_parameters("The profunctor value to transform.")]
521		#[document_returns("The transformed profunctor value.")]
522		#[document_examples]
523		///
524		/// ```
525		/// use fp_library::{
526		/// 	brands::{
527		/// 		optics::*,
528		/// 		*,
529		/// 	},
530		/// 	classes::optics::*,
531		/// 	functions::*,
532		/// 	types::optics::*,
533		/// };
534		///
535		/// let g1: GetterPrime<RcBrand, (i32, String), i32> = GetterPrime::new(|(x, _)| x);
536		/// let g2: GetterPrime<RcBrand, i32, i32> = GetterPrime::new(|x| x);
537		/// let composed = Composed::new(g1, g2);
538		/// let f = Forget::<RcBrand, i32, i32, i32>::new(|x| x);
539		/// let folded = <Composed<
540		/// 	'_,
541		/// 	(i32, String),
542		/// 	(i32, String),
543		/// 	i32,
544		/// 	i32,
545		/// 	i32,
546		/// 	i32,
547		/// 	GetterPrime<RcBrand, (i32, String), i32>,
548		/// 	GetterPrime<RcBrand, i32, i32>,
549		/// > as GetterOptic<(i32, String), i32>>::evaluate::<i32, RcBrand>(&composed, f);
550		/// assert_eq!(folded.run((42, "hi".to_string())), 42);
551		/// ```
552		fn evaluate<R: 'a + 'static, PointerBrand: UnsizedCoercible + 'static>(
553			&self,
554			pab: Apply!(<ForgetBrand<PointerBrand, R> as Kind!( type Of<'b, T: 'b, U: 'b>: 'b; )>::Of<'a, A, A>),
555		) -> Apply!(<ForgetBrand<PointerBrand, R> as Kind!( type Of<'b, T: 'b, U: 'b>: 'b; )>::Of<'a, S, S>)
556		{
557			let pmn = GetterOptic::evaluate::<R, PointerBrand>(&self.second, pab);
558			GetterOptic::evaluate::<R, PointerBrand>(&self.first, pmn)
559		}
560	}
561
562	#[document_type_parameters(
563		"The lifetime of the values.",
564		"The source type of the structure.",
565		"The focus type.",
566		"The intermediate type.",
567		"The first optic.",
568		"The second optic."
569	)]
570	#[document_parameters("The composed optic instance.")]
571	impl<'a, S, A, M, O1, O2> FoldOptic<'a, S, A> for Composed<'a, S, S, M, M, A, A, O1, O2>
572	where
573		O1: FoldOptic<'a, S, M>,
574		O2: FoldOptic<'a, M, A>,
575		M: 'a,
576		A: 'a,
577	{
578		#[document_signature]
579		#[document_type_parameters("The monoid type.", "The reference-counted pointer type.")]
580		#[document_parameters("The profunctor value to transform.")]
581		#[document_returns("The transformed profunctor value.")]
582		#[document_examples]
583		///
584		/// ```
585		/// use fp_library::{
586		/// 	brands::{
587		/// 		optics::*,
588		/// 		*,
589		/// 	},
590		/// 	classes::{
591		/// 		Monoid,
592		/// 		optics::*,
593		/// 	},
594		/// 	functions::*,
595		/// 	types::optics::*,
596		/// };
597		/// let f1: FoldPrime<RcBrand, Vec<i32>, i32, _> = FoldPrime::new(IterableFoldFn(|v: Vec<i32>| v));
598		/// let f2: FoldPrime<RcBrand, i32, i32, _> =
599		/// 	FoldPrime::new(IterableFoldFn(|x: i32| std::iter::once(x)));
600		/// let composed = Composed::new(f1, f2);
601		/// let f = Forget::<RcBrand, String, i32, i32>::new(|x| x.to_string());
602		/// let folded = <Composed<
603		/// 	'_,
604		/// 	Vec<i32>,
605		/// 	Vec<i32>,
606		/// 	i32,
607		/// 	i32,
608		/// 	i32,
609		/// 	i32,
610		/// 	FoldPrime<RcBrand, Vec<i32>, i32, _>,
611		/// 	FoldPrime<RcBrand, i32, i32, _>,
612		/// > as FoldOptic<Vec<i32>, i32>>::evaluate::<String, RcBrand>(&composed, f);
613		/// assert_eq!(folded.run(vec![1, 2, 3]), "123".to_string());
614		/// ```
615		fn evaluate<R: 'a + Monoid + Clone + 'static, PointerBrand: UnsizedCoercible + 'static>(
616			&self,
617			pab: Apply!(<ForgetBrand<PointerBrand, R> as Kind!( type Of<'b, T: 'b, U: 'b>: 'b; )>::Of<'a, A, A>),
618		) -> Apply!(<ForgetBrand<PointerBrand, R> as Kind!( type Of<'b, T: 'b, U: 'b>: 'b; )>::Of<'a, S, S>)
619		{
620			let pmn = FoldOptic::evaluate::<R, PointerBrand>(&self.second, pab);
621			FoldOptic::evaluate::<R, PointerBrand>(&self.first, pmn)
622		}
623	}
624
625	#[document_type_parameters(
626		"The lifetime of the values.",
627		"The reference-counted pointer type for the Setter brand.",
628		"The source type of the outer structure.",
629		"The target type of the outer structure.",
630		"The source type of the intermediate structure.",
631		"The target type of the intermediate structure.",
632		"The source type of the focus.",
633		"The target type of the focus.",
634		"The first optic.",
635		"The second optic."
636	)]
637	#[document_parameters("The composed optic instance.")]
638	impl<'a, PointerBrand, S, T, M, N, A, B, O1, O2> SetterOptic<'a, PointerBrand, S, T, A, B>
639		for Composed<'a, S, T, M, N, A, B, O1, O2>
640	where
641		PointerBrand: UnsizedCoercible,
642		O1: SetterOptic<'a, PointerBrand, S, T, M, N>,
643		O2: SetterOptic<'a, PointerBrand, M, N, A, B>,
644		M: 'a,
645		N: 'a,
646	{
647		#[document_signature]
648		#[document_parameters("The profunctor value to transform.")]
649		#[document_returns("The transformed profunctor value.")]
650		#[document_examples]
651		///
652		/// ```
653		/// use fp_library::{
654		/// 	brands::{
655		/// 		optics::*,
656		/// 		*,
657		/// 	},
658		/// 	classes::optics::*,
659		/// 	functions::*,
660		/// 	types::optics::*,
661		/// };
662		///
663		/// let s1: SetterPrime<RcBrand, (i32, String), i32> =
664		/// 	SetterPrime::new(|(s, f): ((i32, String), Box<dyn Fn(i32) -> i32>)| (f(s.0), s.1));
665		/// let s2: SetterPrime<RcBrand, i32, i32> =
666		/// 	SetterPrime::new(|(s, f): (i32, Box<dyn Fn(i32) -> i32>)| f(s));
667		/// let composed = Composed::new(s1, s2);
668		/// let f = cloneable_fn_new::<RcFnBrand, _, _>(|x: i32| x * 2);
669		/// let modifier =
670		/// 	<Composed<
671		/// 		'_,
672		/// 		(i32, String),
673		/// 		(i32, String),
674		/// 		i32,
675		/// 		i32,
676		/// 		i32,
677		/// 		i32,
678		/// 		SetterPrime<RcBrand, (i32, String), i32>,
679		/// 		SetterPrime<RcBrand, i32, i32>,
680		/// 	> as SetterOptic<RcBrand, (i32, String), (i32, String), i32, i32>>::evaluate(&composed, f);
681		/// assert_eq!(modifier((21, "hi".to_string())), (42, "hi".to_string()));
682		/// ```
683		fn evaluate(
684			&self,
685			pab: Apply!(<FnBrand<PointerBrand> as Kind!( type Of<'b, T: 'b, U: 'b>: 'b; )>::Of<'a, A, B>),
686		) -> Apply!(<FnBrand<PointerBrand> as Kind!( type Of<'b, T: 'b, U: 'b>: 'b; )>::Of<'a, S, T>)
687		{
688			let pmn = SetterOptic::evaluate(&self.second, pab);
689			SetterOptic::evaluate(&self.first, pmn)
690		}
691	}
692
693	#[document_type_parameters(
694		"The lifetime of the values.",
695		"The source type of the outer structure.",
696		"The target type of the outer structure.",
697		"The source type of the intermediate structure.",
698		"The target type of the intermediate structure.",
699		"The source type of the focus.",
700		"The target type of the focus.",
701		"The first optic.",
702		"The second optic."
703	)]
704	#[document_parameters("The composed optic instance.")]
705	impl<'a, S, T, M, N, A, B, O1, O2> ReviewOptic<'a, S, T, A, B>
706		for Composed<'a, S, T, M, N, A, B, O1, O2>
707	where
708		O1: ReviewOptic<'a, S, T, M, N>,
709		O2: ReviewOptic<'a, M, N, A, B>,
710		M: 'a,
711		N: 'a,
712	{
713		#[document_signature]
714		#[document_parameters("The profunctor value to transform.")]
715		#[document_returns("The transformed profunctor value.")]
716		#[document_examples]
717		///
718		/// ```
719		/// use fp_library::{
720		/// 	brands::{
721		/// 		optics::*,
722		/// 		*,
723		/// 	},
724		/// 	classes::optics::*,
725		/// 	functions::*,
726		/// 	types::optics::*,
727		/// };
728		///
729		/// let r1: ReviewPrime<RcBrand, Option<i32>, i32> = ReviewPrime::new(Some);
730		/// let r2: ReviewPrime<RcBrand, i32, i32> = ReviewPrime::new(|x| x);
731		/// let composed = Composed::new(r1, r2);
732		/// let f = Tagged::new(21);
733		/// let reviewed = <Composed<
734		/// 	'_,
735		/// 	Option<i32>,
736		/// 	Option<i32>,
737		/// 	i32,
738		/// 	i32,
739		/// 	i32,
740		/// 	i32,
741		/// 	ReviewPrime<RcBrand, Option<i32>, i32>,
742		/// 	ReviewPrime<RcBrand, i32, i32>,
743		/// > as ReviewOptic<Option<i32>, Option<i32>, i32, i32>>::evaluate(&composed, f);
744		/// assert_eq!(reviewed.0, Some(21));
745		/// ```
746		fn evaluate(
747			&self,
748			pab: Apply!(<TaggedBrand as Kind!( type Of<'b, T: 'b, U: 'b>: 'b; )>::Of<'a, A, B>),
749		) -> Apply!(<TaggedBrand as Kind!( type Of<'b, T: 'b, U: 'b>: 'b; )>::Of<'a, S, T>) {
750			let pmn = ReviewOptic::evaluate(&self.second, pab);
751			ReviewOptic::evaluate(&self.first, pmn)
752		}
753	}
754
755	#[document_type_parameters(
756		"The lifetime of the values.",
757		"The cloneable function brand used by the profunctor's `Closed` instance.",
758		"The source type of the outer structure.",
759		"The target type of the outer structure.",
760		"The source type of the intermediate structure.",
761		"The target type of the intermediate structure.",
762		"The source type of the focus.",
763		"The target type of the focus.",
764		"The first optic.",
765		"The second optic."
766	)]
767	#[document_parameters("The composed optic instance.")]
768	impl<'a, FunctionBrand: CloneableFn, S, T, M, N, A, B, O1, O2>
769		GrateOptic<'a, FunctionBrand, S, T, A, B> for Composed<'a, S, T, M, N, A, B, O1, O2>
770	where
771		O1: GrateOptic<'a, FunctionBrand, S, T, M, N>,
772		O2: GrateOptic<'a, FunctionBrand, M, N, A, B>,
773	{
774		#[document_signature]
775		#[document_type_parameters("The profunctor type.")]
776		#[document_parameters("The profunctor value to transform.")]
777		#[document_returns("The transformed profunctor value.")]
778		#[document_examples]
779		///
780		/// ```
781		/// use fp_library::{
782		/// 	brands::{
783		/// 		optics::*,
784		/// 		*,
785		/// 	},
786		/// 	classes::optics::*,
787		/// 	functions::*,
788		/// 	types::optics::*,
789		/// };
790		///
791		/// // Composition works with lenses too
792		/// let l1: LensPrime<RcBrand, (i32, String), i32> =
793		/// 	LensPrime::from_view_set(|(x, _)| x, |((_, s), x)| (x, s));
794		/// let l2: LensPrime<RcBrand, i32, i32> = LensPrime::from_view_set(|x| x, |(_, x)| x);
795		/// let composed = Composed::new(l1, l2);
796		/// let f = cloneable_fn_new::<RcFnBrand, _, _>(|x: i32| x * 2);
797		/// let modifier = <Composed<
798		/// 	'_,
799		/// 	(i32, String),
800		/// 	(i32, String),
801		/// 	i32,
802		/// 	i32,
803		/// 	i32,
804		/// 	i32,
805		/// 	LensPrime<RcBrand, (i32, String), i32>,
806		/// 	LensPrime<RcBrand, i32, i32>,
807		/// > as Optic<RcFnBrand, _, _, _, _>>::evaluate(&composed, f);
808		/// assert_eq!(modifier((21, "test".to_string())), (42, "test".to_string()));
809		/// ```
810		fn evaluate<P: Closed<FunctionBrand>>(
811			&self,
812			pab: Apply!(<P as Kind!( type Of<'b, T: 'b, U: 'b>: 'b; )>::Of<'a, A, B>),
813		) -> Apply!(<P as Kind!( type Of<'b, T: 'b, U: 'b>: 'b; )>::Of<'a, S, T>) {
814			let pmn = GrateOptic::<FunctionBrand, M, N, A, B>::evaluate::<P>(&self.second, pab);
815			GrateOptic::<FunctionBrand, S, T, M, N>::evaluate::<P>(&self.first, pmn)
816		}
817	}
818
819	/// Compose two optics into a single optic.
820	///
821	/// While PureScript uses the `Semigroupoid` operator (`<<<`) for composition because
822	/// its optics are functions, this library uses a specialized `Composed` struct.
823	/// This is necessary because Rust represents the polymorphic profunctor constraint
824	/// as a parameterized trait (`Optic<'a, P, ...>`), and the `Composed` struct enables
825	/// static dispatch and zero-cost composition through monomorphization.
826	#[document_signature]
827	///
828	#[document_type_parameters(
829		"The lifetime of the values.",
830		"The source type of the outer structure.",
831		"The target type of the outer structure.",
832		"The source type of the intermediate structure.",
833		"The target type of the intermediate structure.",
834		"The source type of the focus.",
835		"The target type of the focus.",
836		"The first optic.",
837		"The second optic."
838	)]
839	///
840	#[document_parameters("The outer optic (applied second).", "The inner optic (applied first).")]
841	///
842	#[document_examples]
843	///
844	/// ```
845	/// use fp_library::{
846	/// 	brands::{
847	/// 		optics::*,
848	/// 		*,
849	/// 	},
850	/// 	classes::optics::*,
851	/// 	functions::*,
852	/// 	types::optics::*,
853	/// };
854	///
855	/// #[derive(Clone, Debug, PartialEq)]
856	/// struct Address {
857	/// 	street: String,
858	/// }
859	/// #[derive(Clone, Debug, PartialEq)]
860	/// struct User {
861	/// 	address: Address,
862	/// }
863	///
864	/// let address_lens: LensPrime<RcBrand, User, Address> = LensPrime::from_view_set(
865	/// 	|u: User| u.address.clone(),
866	/// 	|(_, a)| User {
867	/// 		address: a,
868	/// 	},
869	/// );
870	/// let street_lens: LensPrime<RcBrand, Address, String> = LensPrime::from_view_set(
871	/// 	|a: Address| a.street.clone(),
872	/// 	|(_, s)| Address {
873	/// 		street: s,
874	/// 	},
875	/// );
876	///
877	/// let user_street = optics_compose(address_lens, street_lens);
878	/// let user = User {
879	/// 	address: Address {
880	/// 		street: "High St".to_string(),
881	/// 	},
882	/// };
883	///
884	/// let f = cloneable_fn_new::<RcFnBrand, _, _>(|s: String| s.to_uppercase());
885	/// let modifier = <Composed<
886	/// 	'_,
887	/// 	User,
888	/// 	User,
889	/// 	Address,
890	/// 	Address,
891	/// 	String,
892	/// 	String,
893	/// 	LensPrime<RcBrand, User, Address>,
894	/// 	LensPrime<RcBrand, Address, String>,
895	/// > as Optic<RcFnBrand, _, _, _, _>>::evaluate(&user_street, f);
896	/// let updated = modifier(user);
897	///
898	/// assert_eq!(updated.address.street, "HIGH ST");
899	/// ```
900	pub fn optics_compose<'a, S: 'a, T: 'a, M: 'a, N: 'a, A: 'a, B: 'a, O1, O2>(
901		first: O1,
902		second: O2,
903	) -> Composed<'a, S, T, M, N, A, B, O1, O2> {
904		Composed::new(first, second)
905	}
906
907	#[document_type_parameters(
908		"The lifetime of the values.",
909		"The index type.",
910		"The source type of the outer structure.",
911		"The target type of the outer structure.",
912		"The source type of the intermediate structure.",
913		"The target type of the intermediate structure.",
914		"The source type of the focus.",
915		"The target type of the focus.",
916		"The first optic.",
917		"The second optic."
918	)]
919	#[document_parameters("The composed optic instance.")]
920	impl<'a, I: 'a, S: 'a, T: 'a, M: 'a, N: 'a, A: 'a, B: 'a, O1, O2>
921		IndexedLensOptic<'a, I, S, T, A, B> for Composed<'a, S, T, M, N, A, B, O1, O2>
922	where
923		O1: LensOptic<'a, S, T, M, N>,
924		O2: IndexedLensOptic<'a, I, M, N, A, B>,
925	{
926		#[document_signature]
927		#[document_type_parameters("The profunctor type.")]
928		#[document_parameters("The indexed profunctor value to transform.")]
929		#[document_returns("The transformed profunctor value.")]
930		#[document_examples]
931		///
932		/// ```
933		/// use fp_library::{
934		/// 	brands::{
935		/// 		optics::*,
936		/// 		*,
937		/// 	},
938		/// 	classes::optics::*,
939		/// 	functions::*,
940		/// 	types::optics::*,
941		/// };
942		/// let l1: LensPrime<RcBrand, (i32, String), i32> =
943		/// 	LensPrime::from_view_set(|(x, _)| x, |((_, s), x)| (x, s));
944		/// let l2: IndexedLensPrime<RcBrand, usize, i32, i32> =
945		/// 	IndexedLensPrime::from_iview_set(|x| (0, x), |(_, x)| x);
946		/// let composed = Composed::new(l1, l2);
947		/// let f = |(i, x): (usize, i32)| x + (i as i32);
948		/// let indexed = Indexed::<RcFnBrand, usize, i32, i32>::new(std::rc::Rc::new(f));
949		/// let modifier = <Composed<
950		/// 	'_,
951		/// 	(i32, String),
952		/// 	(i32, String),
953		/// 	i32,
954		/// 	i32,
955		/// 	i32,
956		/// 	i32,
957		/// 	LensPrime<RcBrand, (i32, String), i32>,
958		/// 	IndexedLensPrime<RcBrand, usize, i32, i32>,
959		/// > as IndexedLensOptic<usize, (i32, String), (i32, String), i32, i32>>::evaluate::<RcFnBrand>(
960		/// 	&composed, indexed,
961		/// );
962		/// assert_eq!(modifier((21, "hi".to_string())), (21, "hi".to_string()));
963		/// ```
964		fn evaluate<P: Strong>(
965			&self,
966			pab: crate::types::optics::Indexed<'a, P, I, A, B>,
967		) -> Apply!(<P as Kind!( type Of<'b, T: 'b, U: 'b>: 'b; )>::Of<'a, S, T>) {
968			let pmn = self.second.evaluate(pab);
969			self.first.evaluate::<P>(pmn)
970		}
971	}
972
973	#[document_type_parameters(
974		"The lifetime of the values.",
975		"The index type.",
976		"The source type of the outer structure.",
977		"The target type of the outer structure.",
978		"The source type of the intermediate structure.",
979		"The target type of the intermediate structure.",
980		"The source type of the focus.",
981		"The target type of the focus.",
982		"The first optic.",
983		"The second optic."
984	)]
985	#[document_parameters("The composed optic instance.")]
986	impl<'a, I: 'a, S: 'a, T: 'a, M: 'a, N: 'a, A: 'a, B: 'a, O1, O2>
987		IndexedTraversalOptic<'a, I, S, T, A, B> for Composed<'a, S, T, M, N, A, B, O1, O2>
988	where
989		O1: TraversalOptic<'a, S, T, M, N>,
990		O2: IndexedTraversalOptic<'a, I, M, N, A, B>,
991	{
992		#[document_signature]
993		#[document_type_parameters("The profunctor type.")]
994		#[document_parameters("The indexed profunctor value to transform.")]
995		#[document_returns("The transformed profunctor value.")]
996		#[document_examples]
997		///
998		/// ```
999		/// use fp_library::{
1000		/// 	brands::{
1001		/// 		optics::*,
1002		/// 		*,
1003		/// 	},
1004		/// 	classes::optics::*,
1005		/// 	functions::*,
1006		/// 	types::optics::*,
1007		/// };
1008		/// let l1: LensPrime<RcBrand, (i32, String), i32> =
1009		/// 	LensPrime::from_view_set(|(x, _)| x, |((_, s), x)| (x, s));
1010		/// let l2: IndexedLensPrime<RcBrand, usize, i32, i32> =
1011		/// 	IndexedLensPrime::from_iview_set(|x| (0, x), |(_, x)| x);
1012		/// let composed = Composed::new(l1, l2);
1013		/// let f = |(i, x): (usize, i32)| x + (i as i32);
1014		/// let indexed = Indexed::<RcFnBrand, usize, i32, i32>::new(std::rc::Rc::new(f));
1015		/// let modifier = <Composed<
1016		/// 	'_,
1017		/// 	(i32, String),
1018		/// 	(i32, String),
1019		/// 	i32,
1020		/// 	i32,
1021		/// 	i32,
1022		/// 	i32,
1023		/// 	LensPrime<RcBrand, (i32, String), i32>,
1024		/// 	IndexedLensPrime<RcBrand, usize, i32, i32>,
1025		/// > as IndexedTraversalOptic<usize, (i32, String), (i32, String), i32, i32>>::evaluate::<RcFnBrand>(
1026		/// 	&composed, indexed,
1027		/// );
1028		/// assert_eq!(modifier((21, "hi".to_string())), (21, "hi".to_string()));
1029		/// ```
1030		fn evaluate<P: Wander>(
1031			&self,
1032			pab: crate::types::optics::Indexed<'a, P, I, A, B>,
1033		) -> Apply!(<P as Kind!( type Of<'b, T: 'b, U: 'b>: 'b; )>::Of<'a, S, T>) {
1034			let pmn = self.second.evaluate(pab);
1035			self.first.evaluate::<P>(pmn)
1036		}
1037	}
1038
1039	#[document_type_parameters(
1040		"The lifetime of the values.",
1041		"The index type.",
1042		"The source type of the structure.",
1043		"The focus type.",
1044		"The intermediate type.",
1045		"The first optic.",
1046		"The second optic."
1047	)]
1048	#[document_parameters("The composed optic instance.")]
1049	impl<'a, I: 'a, S: 'a, A: 'a, M: 'a, O1, O2> IndexedGetterOptic<'a, I, S, A>
1050		for Composed<'a, S, S, M, M, A, A, O1, O2>
1051	where
1052		O1: GetterOptic<'a, S, M>,
1053		O2: IndexedGetterOptic<'a, I, M, A>,
1054	{
1055		#[document_signature]
1056		#[document_type_parameters(
1057			"The return type of the forget profunctor.",
1058			"The reference-counted pointer type."
1059		)]
1060		#[document_parameters("The indexed profunctor value to transform.")]
1061		#[document_returns("The transformed profunctor value.")]
1062		#[document_examples]
1063		///
1064		/// ```
1065		/// use fp_library::{
1066		/// 	brands::{
1067		/// 		optics::*,
1068		/// 		*,
1069		/// 	},
1070		/// 	classes::optics::*,
1071		/// 	functions::*,
1072		/// 	types::optics::*,
1073		/// };
1074		/// let l1: GetterPrime<RcBrand, (i32, String), i32> = GetterPrime::new(|(x, _)| x);
1075		/// let l2: IndexedGetterPrime<RcBrand, usize, i32, i32> = IndexedGetterPrime::new(|x| (0, x));
1076		/// let composed = Composed::new(l1, l2);
1077		/// let f = Forget::<RcBrand, (usize, i32), (usize, i32), i32>::new(|(i, x)| (i, x));
1078		/// let folded = <Composed<
1079		/// 	'_,
1080		/// 	(i32, String),
1081		/// 	(i32, String),
1082		/// 	i32,
1083		/// 	i32,
1084		/// 	i32,
1085		/// 	i32,
1086		/// 	GetterPrime<RcBrand, (i32, String), i32>,
1087		/// 	IndexedGetterPrime<RcBrand, usize, i32, i32>,
1088		/// > as IndexedGetterOptic<usize, (i32, String), i32>>::evaluate::<(usize, i32), RcBrand>(
1089		/// 	&composed,
1090		/// 	Indexed::new(f),
1091		/// );
1092		/// assert_eq!(folded.run((42, "hi".to_string())), (0, 42));
1093		/// ```
1094		fn evaluate<R: 'a + 'static, PointerBrand: UnsizedCoercible + 'static>(
1095			&self,
1096			pab: crate::types::optics::Indexed<'a, ForgetBrand<PointerBrand, R>, I, A, A>,
1097		) -> Apply!(<ForgetBrand<PointerBrand, R> as Kind!( type Of<'b, T: 'b, U: 'b>: 'b; )>::Of<'a, S, S>)
1098		{
1099			let pmn = self.second.evaluate::<R, PointerBrand>(pab);
1100			self.first.evaluate::<R, PointerBrand>(pmn)
1101		}
1102	}
1103
1104	#[document_type_parameters(
1105		"The lifetime of the values.",
1106		"The index type.",
1107		"The source type of the structure.",
1108		"The focus type.",
1109		"The intermediate type.",
1110		"The first optic.",
1111		"The second optic."
1112	)]
1113	#[document_parameters("The composed optic instance.")]
1114	impl<'a, I: 'a, S: 'a, A: 'a, M: 'a, O1, O2> IndexedFoldOptic<'a, I, S, A>
1115		for Composed<'a, S, S, M, M, A, A, O1, O2>
1116	where
1117		O1: FoldOptic<'a, S, M>,
1118		O2: IndexedFoldOptic<'a, I, M, A>,
1119	{
1120		#[document_signature]
1121		#[document_type_parameters("The monoid type.", "The reference-counted pointer type.")]
1122		#[document_parameters("The indexed profunctor value to transform.")]
1123		#[document_returns("The transformed profunctor value.")]
1124		#[document_examples]
1125		///
1126		/// ```
1127		/// use fp_library::{
1128		/// 	brands::{
1129		/// 		optics::*,
1130		/// 		*,
1131		/// 	},
1132		/// 	classes::optics::*,
1133		/// 	functions::*,
1134		/// 	types::optics::*,
1135		/// };
1136		/// let l1: GetterPrime<RcBrand, (i32, String), i32> = GetterPrime::new(|(x, _)| x);
1137		/// let l2: IndexedGetterPrime<RcBrand, usize, i32, i32> = IndexedGetterPrime::new(|x| (0, x));
1138		/// let composed = Composed::new(l1, l2);
1139		/// let f = Forget::<RcBrand, String, (usize, i32), i32>::new(|(i, x)| format!("{}:{}", i, x));
1140		/// let folded = <Composed<
1141		/// 	'_,
1142		/// 	(i32, String),
1143		/// 	(i32, String),
1144		/// 	i32,
1145		/// 	i32,
1146		/// 	i32,
1147		/// 	i32,
1148		/// 	GetterPrime<RcBrand, (i32, String), i32>,
1149		/// 	IndexedGetterPrime<RcBrand, usize, i32, i32>,
1150		/// > as IndexedFoldOptic<usize, (i32, String), i32>>::evaluate::<String, RcBrand>(
1151		/// 	&composed,
1152		/// 	Indexed::new(f),
1153		/// );
1154		/// assert_eq!(folded.run((42, "hi".to_string())), "0:42");
1155		/// ```
1156		fn evaluate<R: 'a + Monoid + Clone + 'static, PointerBrand: UnsizedCoercible + 'static>(
1157			&self,
1158			pab: crate::types::optics::Indexed<'a, ForgetBrand<PointerBrand, R>, I, A, A>,
1159		) -> Apply!(<ForgetBrand<PointerBrand, R> as Kind!( type Of<'b, T: 'b, U: 'b>: 'b; )>::Of<'a, S, S>)
1160		{
1161			let pmn = self.second.evaluate::<R, PointerBrand>(pab);
1162			self.first.evaluate::<R, PointerBrand>(pmn)
1163		}
1164	}
1165
1166	#[document_type_parameters(
1167		"The lifetime of the values.",
1168		"The reference-counted pointer type for the Setter brand.",
1169		"The index type.",
1170		"The source type of the outer structure.",
1171		"The target type of the outer structure.",
1172		"The source type of the intermediate structure.",
1173		"The target type of the intermediate structure.",
1174		"The source type of the focus.",
1175		"The target type of the focus.",
1176		"The first optic.",
1177		"The second optic."
1178	)]
1179	#[document_parameters("The composed optic instance.")]
1180	impl<'a, PointerBrand, I: 'a, S: 'a, T: 'a, M: 'a, N: 'a, A: 'a, B: 'a, O1, O2>
1181		IndexedSetterOptic<'a, PointerBrand, I, S, T, A, B> for Composed<'a, S, T, M, N, A, B, O1, O2>
1182	where
1183		PointerBrand: UnsizedCoercible,
1184		O1: SetterOptic<'a, PointerBrand, S, T, M, N>,
1185		O2: IndexedSetterOptic<'a, PointerBrand, I, M, N, A, B>,
1186	{
1187		#[document_signature]
1188		#[document_parameters("The indexed profunctor value to transform.")]
1189		#[document_returns("The transformed profunctor value.")]
1190		#[document_examples]
1191		///
1192		/// ```
1193		/// use fp_library::{
1194		/// 	brands::{
1195		/// 		optics::*,
1196		/// 		*,
1197		/// 	},
1198		/// 	classes::optics::*,
1199		/// 	functions::*,
1200		/// 	types::optics::*,
1201		/// };
1202		/// let l1: LensPrime<RcBrand, (i32, String), i32> =
1203		/// 	LensPrime::from_view_set(|(x, _)| x, |((_, s), x)| (x, s));
1204		/// let l2: IndexedLensPrime<RcBrand, usize, i32, i32> =
1205		/// 	IndexedLensPrime::from_iview_set(|x| (0, x), |(_, x)| x);
1206		/// let composed = Composed::new(l1, l2);
1207		/// let f = |(i, x): (usize, i32)| x + (i as i32);
1208		/// let indexed = Indexed::<RcFnBrand, usize, i32, i32>::new(std::rc::Rc::new(f));
1209		/// let modifier = <Composed<
1210		/// 	'_,
1211		/// 	(i32, String),
1212		/// 	(i32, String),
1213		/// 	i32,
1214		/// 	i32,
1215		/// 	i32,
1216		/// 	i32,
1217		/// 	LensPrime<RcBrand, (i32, String), i32>,
1218		/// 	IndexedLensPrime<RcBrand, usize, i32, i32>,
1219		/// > as IndexedSetterOptic<RcBrand, usize, (i32, String), (i32, String), i32, i32>>::evaluate(
1220		/// 	&composed, indexed,
1221		/// );
1222		/// assert_eq!(modifier((21, "hi".to_string())), (21, "hi".to_string()));
1223		/// ```
1224		fn evaluate(
1225			&self,
1226			pab: crate::types::optics::Indexed<'a, FnBrand<PointerBrand>, I, A, B>,
1227		) -> Apply!(<FnBrand<PointerBrand> as Kind!( type Of<'b, T: 'b, U: 'b>: 'b; )>::Of<'a, S, T>)
1228		{
1229			let pmn = self.second.evaluate(pab);
1230			self.first.evaluate(pmn)
1231		}
1232	}
1233}
1234pub use inner::*;