Skip to main content

fp_library/types/optics/
affine.rs

1//! Affine traversal optics for optional focusing.
2
3#[fp_macros::document_module]
4mod inner {
5	use {
6		crate::{
7			Apply,
8			brands::{
9				FnBrand,
10				optics::*,
11			},
12			classes::{
13				monoid::Monoid,
14				optics::*,
15				profunctor::{
16					Choice,
17					Strong,
18					Wander,
19				},
20				*,
21			},
22			kinds::*,
23		},
24		fp_macros::*,
25	};
26
27	/// A polymorphic affine traversal where types can change.
28	/// This matches PureScript's `AffineTraversal s t a b`.
29	///
30	/// An affine traversal focuses on at most one element. It combines the properties of
31	/// lenses (Strong) and prisms (Choice), allowing optional focusing like a prism but
32	/// without the ability to construct the whole from the part.
33	/// Uses [`FnBrand`](crate::brands::FnBrand) to support capturing closures.
34	#[document_type_parameters(
35		"The lifetime of the values.",
36		"The reference-counted pointer type.",
37		"The source type of the structure.",
38		"The target type of the structure after an update.",
39		"The source type of the focus.",
40		"The target type of the focus after an update."
41	)]
42	pub struct AffineTraversal<'a, PointerBrand, S, T, A, B>
43	where
44		PointerBrand: ToDynCloneFn,
45		S: 'a,
46		T: 'a,
47		A: 'a,
48		B: 'a, {
49		/// Internal storage avoiding S: Clone.
50		pub(crate) to: Apply!(<FnBrand<PointerBrand> as Kind!( type Of<'b, U: 'b, V: 'b>: 'b; )>::Of<'a, S, Result<(A, <FnBrand<PointerBrand> as CloneFn>::Of<'a, B, T>), T>>),
51	}
52
53	#[document_type_parameters(
54		"The lifetime of the values.",
55		"The reference-counted pointer type.",
56		"The source type of the structure.",
57		"The target type of the structure after an update.",
58		"The source type of the focus.",
59		"The target type of the focus after an update."
60	)]
61	#[document_parameters("The affine traversal instance.")]
62	impl<'a, PointerBrand, S, T, A, B> Clone for AffineTraversal<'a, PointerBrand, S, T, A, B>
63	where
64		PointerBrand: ToDynCloneFn,
65		S: 'a,
66		T: 'a,
67		A: 'a,
68		B: 'a,
69	{
70		#[document_signature]
71		#[document_returns("A new `AffineTraversal` instance that is a copy of the original.")]
72		#[document_examples]
73		///
74		/// ```
75		/// use fp_library::{
76		/// 	brands::RcBrand,
77		/// 	types::optics::AffineTraversal,
78		/// };
79		///
80		/// let at: AffineTraversal<RcBrand, (i32, String), (i32, String), i32, i32> =
81		/// 	AffineTraversal::from_preview_set(|(x, s): (i32, String)| Ok(x), |((_, s), x)| (x, s));
82		/// let cloned = at.clone();
83		/// assert_eq!(cloned.preview((42, "hi".to_string())), Ok(42));
84		/// ```
85		fn clone(&self) -> Self {
86			AffineTraversal {
87				to: self.to.clone(),
88			}
89		}
90	}
91
92	#[document_type_parameters(
93		"The lifetime of the values.",
94		"The reference-counted pointer type.",
95		"The source type of the structure.",
96		"The target type of the structure after an update.",
97		"The source type of the focus.",
98		"The target type of the focus after an update."
99	)]
100	#[document_parameters("The affine traversal instance.")]
101	impl<'a, PointerBrand, S: 'a, T: 'a, A: 'a, B: 'a> AffineTraversal<'a, PointerBrand, S, T, A, B>
102	where
103		PointerBrand: ToDynCloneFn,
104	{
105		/// Create a new polymorphic affine traversal.
106		/// This matches PureScript's `affineTraversal'` constructor.
107		#[document_signature]
108		///
109		#[document_parameters("The getter/setter pair function.")]
110		///
111		#[document_returns("A new instance of the type.")]
112		///
113		#[document_examples]
114		///
115		/// ```
116		/// use fp_library::{
117		/// 	brands::{
118		/// 		RcBrand,
119		/// 		RcFnBrand,
120		/// 	},
121		/// 	classes::*,
122		/// 	types::optics::AffineTraversal,
123		/// };
124		///
125		/// let at: AffineTraversal<RcBrand, (i32, String), (i32, String), i32, i32> =
126		/// 	AffineTraversal::new(|(x, s): (i32, String)| {
127		/// 		Ok((x, <RcFnBrand as LiftFn>::new(move |b| (b, s.clone()))))
128		/// 	});
129		/// assert_eq!(at.preview((42, "hi".to_string())), Ok(42));
130		/// ```
131		pub fn new(
132			to: impl 'a + Fn(S) -> Result<(A, <FnBrand<PointerBrand> as CloneFn>::Of<'a, B, T>), T>
133		) -> Self {
134			AffineTraversal {
135				to: <FnBrand<PointerBrand> as LiftFn>::new(to),
136			}
137		}
138
139		/// Create a new polymorphic affine traversal from preview and set functions.
140		#[document_signature]
141		///
142		#[document_parameters("The preview function.", "The set function.")]
143		///
144		#[document_returns("A new `AffineTraversal` instance.")]
145		///
146		#[document_examples]
147		///
148		/// ```
149		/// use fp_library::{
150		/// 	brands::RcBrand,
151		/// 	types::optics::AffineTraversal,
152		/// };
153		///
154		/// let at: AffineTraversal<RcBrand, (i32, String), (i32, String), i32, i32> =
155		/// 	AffineTraversal::from_preview_set(|(x, s): (i32, String)| Ok(x), |((_, s), x)| (x, s));
156		/// assert_eq!(at.preview((42, "hi".to_string())), Ok(42));
157		/// ```
158		pub fn from_preview_set(
159			preview: impl 'a + Fn(S) -> Result<A, T>,
160			set: impl 'a + Fn((S, B)) -> T,
161		) -> Self
162		where
163			S: Clone, {
164			let preview_brand = <FnBrand<PointerBrand> as LiftFn>::new(preview);
165			let set_brand = <FnBrand<PointerBrand> as LiftFn>::new(set);
166
167			AffineTraversal {
168				to: <FnBrand<PointerBrand> as LiftFn>::new(move |s: S| {
169					let s_clone = s.clone();
170					let set_brand = set_brand.clone();
171					match preview_brand(s) {
172						Ok(a) => Ok((
173							a,
174							<FnBrand<PointerBrand> as LiftFn>::new(move |b| {
175								set_brand((s_clone.clone(), b))
176							}),
177						)),
178						Err(t) => Err(t),
179					}
180				}),
181			}
182		}
183
184		/// Preview the focus of the affine traversal in a structure.
185		#[document_signature]
186		///
187		#[document_parameters("The structure to preview.")]
188		///
189		#[document_returns(
190			"A result containing the focus value if it exists, or the original structure (possibly with changed type) if not."
191		)]
192		///
193		#[document_examples]
194		///
195		/// ```
196		/// use fp_library::{
197		/// 	brands::RcBrand,
198		/// 	types::optics::AffineTraversal,
199		/// };
200		///
201		/// let at: AffineTraversal<RcBrand, (i32, String), (i32, String), i32, i32> =
202		/// 	AffineTraversal::from_preview_set(|(x, s): (i32, String)| Ok(x), |((_, s), x)| (x, s));
203		/// assert_eq!(at.preview((42, "hi".to_string())), Ok(42));
204		/// ```
205		pub fn preview(
206			&self,
207			s: S,
208		) -> Result<A, T> {
209			(self.to)(s).map(|(a, _)| a)
210		}
211
212		/// Set the focus in the structure.
213		#[document_signature]
214		///
215		#[document_parameters("The structure to update.", "The new focus value.")]
216		///
217		#[document_returns("The updated structure.")]
218		///
219		#[document_examples]
220		///
221		/// ```
222		/// use fp_library::{
223		/// 	brands::RcBrand,
224		/// 	types::optics::AffineTraversal,
225		/// };
226		///
227		/// let at: AffineTraversal<RcBrand, (i32, String), (i32, String), i32, i32> =
228		/// 	AffineTraversal::from_preview_set(|(x, _)| Ok(x), |((_, s), x)| (x, s));
229		/// assert_eq!(at.set((42, "hi".to_string()), 99), (99, "hi".to_string()));
230		/// ```
231		pub fn set(
232			&self,
233			s: S,
234			b: B,
235		) -> T {
236			match (self.to)(s) {
237				Ok((_, f)) => f(b),
238				Err(t) => t,
239			}
240		}
241	}
242
243	#[document_type_parameters(
244		"The lifetime of the values.",
245		"The profunctor type.",
246		"The reference-counted pointer type.",
247		"The source type of the structure.",
248		"The target type of the structure after an update.",
249		"The source type of the focus.",
250		"The target type of the focus after an update."
251	)]
252	#[document_parameters("The affine traversal instance.")]
253	impl<'a, Q, PointerBrand, S, T, A, B> Optic<'a, Q, S, T, A, B>
254		for AffineTraversal<'a, PointerBrand, S, T, A, B>
255	where
256		Q: Strong + Choice,
257		PointerBrand: ToDynCloneFn,
258		S: 'a,
259		T: 'a,
260		A: 'a,
261		B: 'a,
262	{
263		#[document_signature]
264		#[document_parameters("The profunctor value to transform.")]
265		#[document_returns("The transformed profunctor value.")]
266		#[document_examples]
267		///
268		/// ```
269		/// use fp_library::{
270		/// 	brands::{
271		/// 		optics::*,
272		/// 		*,
273		/// 	},
274		/// 	classes::optics::*,
275		/// 	functions::*,
276		/// 	types::optics::*,
277		/// };
278		///
279		/// let at: AffineTraversal<RcBrand, (i32, String), (i32, String), i32, i32> =
280		/// 	AffineTraversal::from_preview_set(|(x, s): (i32, String)| Ok(x), |((_, s), x)| (x, s));
281		///
282		/// let f = lift_fn_new::<RcFnBrand, _, _>(|x: i32| x * 2);
283		/// let modifier = <AffineTraversal<RcBrand, (i32, String), (i32, String), i32, i32> as Optic<
284		/// 	RcFnBrand,
285		/// 	_,
286		/// 	_,
287		/// 	_,
288		/// 	_,
289		/// >>::evaluate(&at, f);
290		/// assert_eq!(modifier((21, "hello".to_string())), (42, "hello".to_string()));
291		/// ```
292		fn evaluate(
293			&self,
294			pab: Apply!(<Q as Kind!( type Of<'b, T: 'b, U: 'b>: 'b; )>::Of<'a, A, B>),
295		) -> Apply!(<Q as Kind!( type Of<'b, T: 'b, U: 'b>: 'b; )>::Of<'a, S, T>) {
296			let to = self.to.clone();
297
298			Q::dimap(
299				move |s: S| to(s),
300				move |result: Result<(B, <FnBrand<PointerBrand> as CloneFn>::Of<'a, B, T>), T>| {
301					match result {
302						Ok((b, f)) => f(b),
303						Err(t) => t,
304					}
305				},
306				Q::right(Q::first(pab)),
307			)
308		}
309	}
310
311	#[document_type_parameters(
312		"The lifetime of the values.",
313		"The reference-counted pointer type.",
314		"The source type of the structure.",
315		"The target type of the structure after an update.",
316		"The source type of the focus.",
317		"The target type of the focus after an update."
318	)]
319	#[document_parameters("The affine traversal instance.")]
320	impl<'a, PointerBrand, S, T, A, B> AffineTraversalOptic<'a, S, T, A, B>
321		for AffineTraversal<'a, PointerBrand, S, T, A, B>
322	where
323		PointerBrand: ToDynCloneFn,
324		S: 'a,
325		T: 'a,
326		A: 'a,
327		B: 'a,
328	{
329		#[document_signature]
330		#[document_type_parameters("The profunctor type.")]
331		#[document_parameters("The profunctor value to transform.")]
332		#[document_returns("The transformed profunctor value.")]
333		#[document_examples]
334		///
335		/// ```
336		/// use fp_library::{
337		/// 	brands::{
338		/// 		optics::*,
339		/// 		*,
340		/// 	},
341		/// 	classes::optics::*,
342		/// 	functions::*,
343		/// 	types::optics::*,
344		/// };
345		///
346		/// let at: AffineTraversal<RcBrand, (i32, String), (i32, String), i32, i32> =
347		/// 	AffineTraversal::from_preview_set(|(x, s): (i32, String)| Ok(x), |((_, s), x)| (x, s));
348		///
349		/// let f = lift_fn_new::<RcFnBrand, _, _>(|x: i32| x * 2);
350		/// let modifier =
351		/// 	<AffineTraversal<RcBrand, (i32, String), (i32, String), i32, i32> as AffineTraversalOptic<
352		/// 		(i32, String),
353		/// 		(i32, String),
354		/// 		i32,
355		/// 		i32,
356		/// 	>>::evaluate::<RcFnBrand>(&at, f);
357		/// assert_eq!(modifier((21, "hello".to_string())), (42, "hello".to_string()));
358		/// ```
359		fn evaluate<R: Strong + Choice>(
360			&self,
361			pab: Apply!(<R as Kind!( type Of<'b, T: 'b, U: 'b>: 'b; )>::Of<'a, A, B>),
362		) -> Apply!(<R as Kind!( type Of<'b, T: 'b, U: 'b>: 'b; )>::Of<'a, S, T>) {
363			Optic::<R, S, T, A, B>::evaluate(self, pab)
364		}
365	}
366
367	#[document_type_parameters(
368		"The lifetime of the values.",
369		"The reference-counted pointer type.",
370		"The source type of the structure.",
371		"The target type of the structure after an update.",
372		"The source type of the focus.",
373		"The target type of the focus after an update."
374	)]
375	#[document_parameters("The affine traversal instance.")]
376	impl<'a, PointerBrand, S: 'a, T: 'a, A: 'a, B: 'a> TraversalOptic<'a, S, T, A, B>
377		for AffineTraversal<'a, PointerBrand, S, T, A, B>
378	where
379		PointerBrand: ToDynCloneFn,
380	{
381		#[document_signature]
382		#[document_type_parameters("The profunctor type.")]
383		#[document_parameters("The profunctor value to transform.")]
384		#[document_returns("The transformed profunctor value.")]
385		#[document_examples]
386		///
387		/// ```
388		/// use fp_library::{
389		/// 	brands::{
390		/// 		optics::*,
391		/// 		*,
392		/// 	},
393		/// 	classes::optics::*,
394		/// 	functions::*,
395		/// 	types::optics::*,
396		/// };
397		///
398		/// let at: AffineTraversal<RcBrand, (i32, String), (i32, String), i32, i32> =
399		/// 	AffineTraversal::from_preview_set(|(x, s): (i32, String)| Ok(x), |((_, s), x)| (x, s));
400		///
401		/// let f = lift_fn_new::<RcFnBrand, _, _>(|x: i32| x * 2);
402		/// let modifier =
403		/// 	<AffineTraversal<RcBrand, (i32, String), (i32, String), i32, i32> as TraversalOptic<
404		/// 		(i32, String),
405		/// 		(i32, String),
406		/// 		i32,
407		/// 		i32,
408		/// 	>>::evaluate::<RcFnBrand>(&at, f);
409		/// assert_eq!(modifier((21, "hello".to_string())), (42, "hello".to_string()));
410		/// ```
411		fn evaluate<Q: Wander>(
412			&self,
413			pab: Apply!(<Q as Kind!( type Of<'b, T: 'b, U: 'b>: 'b; )>::Of<'a, A, B>),
414		) -> Apply!(<Q as Kind!( type Of<'b, T: 'b, U: 'b>: 'b; )>::Of<'a, S, T>) {
415			Optic::<Q, S, T, A, B>::evaluate(self, pab)
416		}
417	}
418
419	#[document_type_parameters(
420		"The lifetime of the values.",
421		"The reference-counted pointer type.",
422		"The type of the structure.",
423		"The type of the focus."
424	)]
425	#[document_parameters("The affine traversal instance.")]
426	impl<'a, PointerBrand, S: 'a, A: 'a> FoldOptic<'a, S, A>
427		for AffineTraversal<'a, PointerBrand, S, S, A, A>
428	where
429		PointerBrand: ToDynCloneFn,
430	{
431		#[document_signature]
432		#[document_type_parameters(
433			"The monoid type.",
434			"The reference-counted pointer type for the Forget brand."
435		)]
436		#[document_parameters("The profunctor value to transform.")]
437		#[document_returns("The transformed profunctor value.")]
438		#[document_examples]
439		///
440		/// ```
441		/// use fp_library::{
442		/// 	brands::{
443		/// 		optics::*,
444		/// 		*,
445		/// 	},
446		/// 	classes::optics::*,
447		/// 	functions::*,
448		/// 	types::optics::*,
449		/// };
450		///
451		/// let at: AffineTraversal<RcBrand, (i32, String), (i32, String), i32, i32> =
452		/// 	AffineTraversal::from_preview_set(|(x, s): (i32, String)| Ok(x), |((_, s), x)| (x, s));
453		///
454		/// let f = Forget::<RcBrand, String, i32, i32>::new(|x| x.to_string());
455		/// let folded = <AffineTraversal<RcBrand, (i32, String), (i32, String), i32, i32> as FoldOptic<
456		/// 	(i32, String),
457		/// 	i32,
458		/// >>::evaluate::<String, RcBrand>(&at, f);
459		/// assert_eq!(folded.run((42, "hello".to_string())), "42".to_string());
460		/// ```
461		fn evaluate<R: 'a + Monoid + 'static, Q: ToDynCloneFn + 'static>(
462			&self,
463			pab: Apply!(<ForgetBrand<Q, R> as Kind!( type Of<'b, T: 'b, U: 'b>: 'b; )>::Of<'a, A, A>),
464		) -> Apply!(<ForgetBrand<Q, R> as Kind!( type Of<'b, T: 'b, U: 'b>: 'b; )>::Of<'a, S, S>)
465		{
466			Optic::<ForgetBrand<Q, R>, S, S, A, A>::evaluate(self, pab)
467		}
468	}
469
470	#[document_type_parameters(
471		"The lifetime of the values.",
472		"The profunctor type.",
473		"The reference-counted pointer type.",
474		"The source type of the structure.",
475		"The target type of the structure after an update.",
476		"The source type of the focus.",
477		"The target type of the focus after an update."
478	)]
479	#[document_parameters("The affine traversal instance.")]
480	impl<'a, Q, PointerBrand, S: 'a, T: 'a, A: 'a, B: 'a> SetterOptic<'a, Q, S, T, A, B>
481		for AffineTraversal<'a, PointerBrand, S, T, A, B>
482	where
483		PointerBrand: ToDynCloneFn,
484		Q: ToDynCloneFn,
485	{
486		#[document_signature]
487		#[document_parameters("The profunctor value to transform.")]
488		#[document_returns("The transformed profunctor value.")]
489		#[document_examples]
490		///
491		/// ```
492		/// use fp_library::{
493		/// 	brands::{
494		/// 		optics::*,
495		/// 		*,
496		/// 	},
497		/// 	classes::optics::*,
498		/// 	functions::*,
499		/// 	types::optics::*,
500		/// };
501		///
502		/// let at: AffineTraversal<RcBrand, (i32, String), (i32, String), i32, i32> =
503		/// 	AffineTraversal::from_preview_set(|(x, s): (i32, String)| Ok(x), |((_, s), x)| (x, s));
504		///
505		/// let f = lift_fn_new::<RcFnBrand, _, _>(|x: i32| x * 2);
506		/// let modifier =
507		/// 	<AffineTraversal<RcBrand, (i32, String), (i32, String), i32, i32> as SetterOptic<
508		/// 		RcBrand,
509		/// 		_,
510		/// 		_,
511		/// 		_,
512		/// 		_,
513		/// 	>>::evaluate(&at, f);
514		/// assert_eq!(modifier((21, "hello".to_string())), (42, "hello".to_string()));
515		/// ```
516		fn evaluate(
517			&self,
518			pab: Apply!(<FnBrand<Q> as Kind!( type Of<'b, T: 'b, U: 'b>: 'b; )>::Of<'a, A, B>),
519		) -> Apply!(<FnBrand<Q> as Kind!( type Of<'b, T: 'b, U: 'b>: 'b; )>::Of<'a, S, T>) {
520			Optic::<FnBrand<Q>, S, T, A, B>::evaluate(self, pab)
521		}
522	}
523
524	/// A concrete affine traversal type where types do not change.
525	/// This matches PureScript's `AffineTraversal' s a`.
526	///
527	/// Uses [`FnBrand`](crate::brands::FnBrand) to support capturing closures.
528	#[document_type_parameters(
529		"The lifetime of the values.",
530		"The reference-counted pointer type.",
531		"The type of the structure.",
532		"The type of the focus."
533	)]
534	pub struct AffineTraversalPrime<'a, PointerBrand, S, A>
535	where
536		PointerBrand: ToDynCloneFn,
537		S: 'a,
538		A: 'a, {
539		pub(crate) to: Apply!(<FnBrand<PointerBrand> as Kind!( type Of<'b, U: 'b, V: 'b>: 'b; )>::Of<'a, S, Result<(A, <FnBrand<PointerBrand> as CloneFn>::Of<'a, A, S>), S>>),
540	}
541
542	#[document_type_parameters(
543		"The lifetime of the values.",
544		"The reference-counted pointer type.",
545		"The type of the structure.",
546		"The type of the focus."
547	)]
548	#[document_parameters("The affine traversal instance.")]
549	impl<'a, PointerBrand, S, A> Clone for AffineTraversalPrime<'a, PointerBrand, S, A>
550	where
551		PointerBrand: ToDynCloneFn,
552		S: 'a,
553		A: 'a,
554	{
555		#[document_signature]
556		#[document_returns("A new `AffineTraversalPrime` instance that is a copy of the original.")]
557		#[document_examples]
558		///
559		/// ```
560		/// use fp_library::{
561		/// 	brands::RcBrand,
562		/// 	types::optics::AffineTraversalPrime,
563		/// };
564		///
565		/// let at: AffineTraversalPrime<RcBrand, (i32, String), i32> =
566		/// 	AffineTraversalPrime::from_preview_set(|(x, _)| Some(x), |((_, s), x)| (x, s));
567		/// let cloned = at.clone();
568		/// assert_eq!(cloned.preview((42, "hi".to_string())), Some(42));
569		/// ```
570		fn clone(&self) -> Self {
571			AffineTraversalPrime {
572				to: self.to.clone(),
573			}
574		}
575	}
576
577	#[document_type_parameters(
578		"The lifetime of the values.",
579		"The reference-counted pointer type.",
580		"The type of the structure.",
581		"The type of the focus."
582	)]
583	#[document_parameters("The monomorphic affine traversal instance.")]
584	impl<'a, PointerBrand, S: 'a, A: 'a> AffineTraversalPrime<'a, PointerBrand, S, A>
585	where
586		PointerBrand: ToDynCloneFn,
587	{
588		/// Create a new monomorphic affine traversal.
589		/// This matches PureScript's `affineTraversal'` constructor.
590		#[document_signature]
591		///
592		#[document_parameters("The getter/setter pair function.")]
593		///
594		#[document_returns("A new instance of the type.")]
595		///
596		#[document_examples]
597		///
598		/// ```
599		/// use fp_library::{
600		/// 	brands::{
601		/// 		RcBrand,
602		/// 		RcFnBrand,
603		/// 	},
604		/// 	classes::*,
605		/// 	types::optics::AffineTraversalPrime,
606		/// };
607		///
608		/// let at: AffineTraversalPrime<RcBrand, (i32, String), i32> =
609		/// 	AffineTraversalPrime::new(|(x, s): (i32, String)| {
610		/// 		Ok((x, <RcFnBrand as LiftFn>::new(move |a| (a, s.clone()))))
611		/// 	});
612		/// assert_eq!(at.preview((42, "hi".to_string())), Some(42));
613		/// ```
614		pub fn new(
615			to: impl 'a + Fn(S) -> Result<(A, <FnBrand<PointerBrand> as CloneFn>::Of<'a, A, S>), S>
616		) -> Self {
617			AffineTraversalPrime {
618				to: <FnBrand<PointerBrand> as LiftFn>::new(to),
619			}
620		}
621
622		/// Create a new monomorphic affine traversal from preview and set functions.
623		#[document_signature]
624		///
625		#[document_parameters("The preview function.", "The set function.")]
626		///
627		#[document_returns("A new `AffineTraversalPrime` instance.")]
628		///
629		#[document_examples]
630		///
631		/// ```
632		/// use fp_library::{
633		/// 	brands::RcBrand,
634		/// 	types::optics::AffineTraversalPrime,
635		/// };
636		///
637		/// let at: AffineTraversalPrime<RcBrand, (i32, String), i32> =
638		/// 	AffineTraversalPrime::from_preview_set(|(x, _)| Some(x), |((_, s), x)| (x, s));
639		/// assert_eq!(at.preview((42, "hi".to_string())), Some(42));
640		/// ```
641		pub fn from_preview_set(
642			preview: impl 'a + Fn(S) -> Option<A>,
643			set: impl 'a + Fn((S, A)) -> S,
644		) -> Self
645		where
646			S: Clone, {
647			let preview_brand = <FnBrand<PointerBrand> as LiftFn>::new(preview);
648			let set_brand = <FnBrand<PointerBrand> as LiftFn>::new(set);
649
650			AffineTraversalPrime {
651				to: <FnBrand<PointerBrand> as LiftFn>::new(move |s: S| {
652					let s_clone = s.clone();
653					let set_brand = set_brand.clone();
654					match preview_brand(s.clone()) {
655						Some(a) => Ok((
656							a,
657							<FnBrand<PointerBrand> as LiftFn>::new(move |a| {
658								set_brand((s_clone.clone(), a))
659							}),
660						)),
661						None => Err(s),
662					}
663				}),
664			}
665		}
666
667		/// Preview the focus of the affine traversal in a structure.
668		#[document_signature]
669		///
670		#[document_parameters("The structure to preview.")]
671		///
672		#[document_returns("The focus value if it exists, or `None` if not.")]
673		///
674		#[document_examples]
675		///
676		/// ```
677		/// use fp_library::{
678		/// 	brands::RcBrand,
679		/// 	types::optics::AffineTraversalPrime,
680		/// };
681		///
682		/// let at: AffineTraversalPrime<RcBrand, (i32, String), i32> =
683		/// 	AffineTraversalPrime::from_preview_set(|(x, _)| Some(x), |((_, s), x)| (x, s));
684		/// assert_eq!(at.preview((42, "hi".to_string())), Some(42));
685		/// ```
686		pub fn preview(
687			&self,
688			s: S,
689		) -> Option<A> {
690			(self.to)(s).ok().map(|(a, _)| a)
691		}
692
693		/// Set the focus in the structure.
694		#[document_signature]
695		///
696		#[document_parameters("The structure to update.", "The new focus value.")]
697		///
698		#[document_returns("The updated structure.")]
699		///
700		#[document_examples]
701		///
702		/// ```
703		/// use fp_library::{
704		/// 	brands::RcBrand,
705		/// 	types::optics::AffineTraversalPrime,
706		/// };
707		///
708		/// let at: AffineTraversalPrime<RcBrand, (i32, String), i32> =
709		/// 	AffineTraversalPrime::from_preview_set(|(x, _)| Some(x), |((_, s), x)| (x, s));
710		/// assert_eq!(at.set((42, "hi".to_string()), 99), (99, "hi".to_string()));
711		/// ```
712		pub fn set(
713			&self,
714			s: S,
715			a: A,
716		) -> S {
717			match (self.to)(s) {
718				Ok((_, f)) => f(a),
719				Err(s) => s,
720			}
721		}
722
723		/// Modify the focus if it exists.
724		#[document_signature]
725		///
726		#[document_parameters("The structure to update.", "The function to apply to the focus.")]
727		///
728		#[document_returns("The updated structure.")]
729		///
730		#[document_examples]
731		///
732		/// ```
733		/// use fp_library::{
734		/// 	brands::RcBrand,
735		/// 	types::optics::AffineTraversalPrime,
736		/// };
737		///
738		/// let at: AffineTraversalPrime<RcBrand, (i32, String), i32> =
739		/// 	AffineTraversalPrime::from_preview_set(|(x, _)| Some(x), |((_, s), x)| (x, s));
740		/// assert_eq!(at.modify((21, "hi".to_string()), |x| x * 2), (42, "hi".to_string()));
741		/// ```
742		pub fn modify(
743			&self,
744			s: S,
745			f: impl Fn(A) -> A,
746		) -> S {
747			match (self.to)(s) {
748				Ok((a, set)) => set(f(a)),
749				Err(s) => s,
750			}
751		}
752	}
753
754	// Optic implementation for AffineTraversalPrime<PointerBrand, S, A>
755	#[document_type_parameters(
756		"The lifetime of the values.",
757		"The profunctor type.",
758		"The reference-counted pointer type.",
759		"The type of the structure.",
760		"The type of the focus."
761	)]
762	#[document_parameters("The monomorphic affine traversal instance.")]
763	impl<'a, Q, PointerBrand, S, A> Optic<'a, Q, S, S, A, A>
764		for AffineTraversalPrime<'a, PointerBrand, S, A>
765	where
766		Q: Strong + Choice,
767		PointerBrand: ToDynCloneFn,
768		S: 'a,
769		A: 'a,
770	{
771		#[document_signature]
772		#[document_parameters("The profunctor value to transform.")]
773		#[document_returns("The transformed profunctor value.")]
774		#[document_examples]
775		///
776		/// ```
777		/// use fp_library::{
778		/// 	brands::{
779		/// 		optics::*,
780		/// 		*,
781		/// 	},
782		/// 	classes::optics::*,
783		/// 	functions::*,
784		/// 	types::optics::*,
785		/// };
786		///
787		/// let at: AffineTraversalPrime<RcBrand, (i32, String), i32> =
788		/// 	AffineTraversalPrime::from_preview_set(|(x, _)| Some(x), |((_, s), x)| (x, s));
789		///
790		/// let f = lift_fn_new::<RcFnBrand, _, _>(|x: i32| x * 2);
791		/// let modifier = <AffineTraversalPrime<RcBrand, (i32, String), i32> as Optic<
792		/// 	RcFnBrand,
793		/// 	_,
794		/// 	_,
795		/// 	_,
796		/// 	_,
797		/// >>::evaluate(&at, f);
798		/// assert_eq!(modifier((21, "hello".to_string())), (42, "hello".to_string()));
799		/// ```
800		fn evaluate(
801			&self,
802			pab: Apply!(<Q as Kind!( type Of<'b, T: 'b, U: 'b>: 'b; )>::Of<'a, A, A>),
803		) -> Apply!(<Q as Kind!( type Of<'b, T: 'b, U: 'b>: 'b; )>::Of<'a, S, S>) {
804			let to = self.to.clone();
805
806			Q::dimap(
807				move |s: S| to(s),
808				move |result: Result<(A, <FnBrand<PointerBrand> as CloneFn>::Of<'a, A, S>), S>| {
809					match result {
810						Ok((a, f)) => f(a),
811						Err(s) => s,
812					}
813				},
814				Q::right(Q::first(pab)),
815			)
816		}
817	}
818
819	#[document_type_parameters(
820		"The lifetime of the values.",
821		"The reference-counted pointer type.",
822		"The type of the structure.",
823		"The type of the focus."
824	)]
825	#[document_parameters("The monomorphic affine traversal instance.")]
826	impl<'a, PointerBrand, S, A> AffineTraversalOptic<'a, S, S, A, A>
827		for AffineTraversalPrime<'a, PointerBrand, S, A>
828	where
829		PointerBrand: ToDynCloneFn,
830		S: 'a,
831		A: 'a,
832	{
833		#[document_signature]
834		#[document_type_parameters("The profunctor type.")]
835		#[document_parameters("The profunctor value to transform.")]
836		#[document_returns("The transformed profunctor value.")]
837		#[document_examples]
838		///
839		/// ```
840		/// use fp_library::{
841		/// 	brands::{
842		/// 		optics::*,
843		/// 		*,
844		/// 	},
845		/// 	classes::optics::*,
846		/// 	functions::*,
847		/// 	types::optics::*,
848		/// };
849		///
850		/// let at: AffineTraversalPrime<RcBrand, (i32, String), i32> =
851		/// 	AffineTraversalPrime::from_preview_set(|(x, _)| Some(x), |((_, s), x)| (x, s));
852		///
853		/// let f = lift_fn_new::<RcFnBrand, _, _>(|x: i32| x * 2);
854		/// let modifier = <AffineTraversalPrime<RcBrand, (i32, String), i32> as AffineTraversalOptic<
855		/// 	(i32, String),
856		/// 	(i32, String),
857		/// 	i32,
858		/// 	i32,
859		/// >>::evaluate::<RcFnBrand>(&at, f);
860		/// assert_eq!(modifier((21, "hello".to_string())), (42, "hello".to_string()));
861		/// ```
862		fn evaluate<R: Strong + Choice>(
863			&self,
864			pab: Apply!(<R as Kind!( type Of<'b, T: 'b, U: 'b>: 'b; )>::Of<'a, A, A>),
865		) -> Apply!(<R as Kind!( type Of<'b, T: 'b, U: 'b>: 'b; )>::Of<'a, S, S>) {
866			Optic::<R, S, S, A, A>::evaluate(self, pab)
867		}
868	}
869
870	#[document_type_parameters(
871		"The lifetime of the values.",
872		"The reference-counted pointer type.",
873		"The type of the structure.",
874		"The type of the focus."
875	)]
876	#[document_parameters("The monomorphic affine traversal instance.")]
877	impl<'a, PointerBrand, S: 'a, A: 'a> TraversalOptic<'a, S, S, A, A>
878		for AffineTraversalPrime<'a, PointerBrand, S, A>
879	where
880		PointerBrand: ToDynCloneFn,
881	{
882		#[document_signature]
883		#[document_type_parameters("The profunctor type.")]
884		#[document_parameters("The profunctor value to transform.")]
885		#[document_returns("The transformed profunctor value.")]
886		#[document_examples]
887		///
888		/// ```
889		/// use fp_library::{
890		/// 	brands::{
891		/// 		optics::*,
892		/// 		*,
893		/// 	},
894		/// 	classes::optics::*,
895		/// 	functions::*,
896		/// 	types::optics::*,
897		/// };
898		///
899		/// let at: AffineTraversalPrime<RcBrand, (i32, String), i32> =
900		/// 	AffineTraversalPrime::from_preview_set(|(x, _)| Some(x), |((_, s), x)| (x, s));
901		///
902		/// let f = lift_fn_new::<RcFnBrand, _, _>(|x: i32| x * 2);
903		/// let modifier = <AffineTraversalPrime<RcBrand, (i32, String), i32> as TraversalOptic<
904		/// 	(i32, String),
905		/// 	(i32, String),
906		/// 	i32,
907		/// 	i32,
908		/// >>::evaluate::<RcFnBrand>(&at, f);
909		/// assert_eq!(modifier((21, "hello".to_string())), (42, "hello".to_string()));
910		/// ```
911		fn evaluate<Q: Wander>(
912			&self,
913			pab: Apply!(<Q as Kind!( type Of<'b, T: 'b, U: 'b>: 'b; )>::Of<'a, A, A>),
914		) -> Apply!(<Q as Kind!( type Of<'b, T: 'b, U: 'b>: 'b; )>::Of<'a, S, S>) {
915			Optic::<Q, S, S, A, A>::evaluate(self, pab)
916		}
917	}
918
919	#[document_type_parameters(
920		"The lifetime of the values.",
921		"The reference-counted pointer type.",
922		"The type of the structure.",
923		"The type of the focus."
924	)]
925	#[document_parameters("The monomorphic affine traversal instance.")]
926	impl<'a, PointerBrand, S: 'a, A: 'a> FoldOptic<'a, S, A>
927		for AffineTraversalPrime<'a, PointerBrand, S, A>
928	where
929		PointerBrand: ToDynCloneFn,
930	{
931		#[document_signature]
932		#[document_type_parameters(
933			"The monoid type.",
934			"The reference-counted pointer type for the Forget brand."
935		)]
936		#[document_parameters("The profunctor value to transform.")]
937		#[document_returns("The transformed profunctor value.")]
938		#[document_examples]
939		///
940		/// ```
941		/// use fp_library::{
942		/// 	brands::{
943		/// 		optics::*,
944		/// 		*,
945		/// 	},
946		/// 	classes::optics::*,
947		/// 	functions::*,
948		/// 	types::optics::*,
949		/// };
950		///
951		/// let at: AffineTraversalPrime<RcBrand, (i32, String), i32> =
952		/// 	AffineTraversalPrime::from_preview_set(|(x, _)| Some(x), |((_, s), x)| (x, s));
953		///
954		/// let f = Forget::<RcBrand, String, i32, i32>::new(|x| x.to_string());
955		/// let folded = <AffineTraversalPrime<RcBrand, (i32, String), i32> as FoldOptic<
956		/// 	(i32, String),
957		/// 	i32,
958		/// >>::evaluate::<String, RcBrand>(&at, f);
959		/// assert_eq!(folded.run((42, "hello".to_string())), "42".to_string());
960		/// ```
961		fn evaluate<R: 'a + Monoid + 'static, Q: ToDynCloneFn + 'static>(
962			&self,
963			pab: Apply!(<ForgetBrand<Q, R> as Kind!( type Of<'b, T: 'b, U: 'b>: 'b; )>::Of<'a, A, A>),
964		) -> Apply!(<ForgetBrand<Q, R> as Kind!( type Of<'b, T: 'b, U: 'b>: 'b; )>::Of<'a, S, S>)
965		{
966			Optic::<ForgetBrand<Q, R>, S, S, A, A>::evaluate(self, pab)
967		}
968	}
969
970	#[document_type_parameters(
971		"The lifetime of the values.",
972		"The profunctor type.",
973		"The reference-counted pointer type.",
974		"The type of the structure.",
975		"The type of the focus."
976	)]
977	#[document_parameters("The monomorphic affine traversal instance.")]
978	impl<'a, Q, PointerBrand, S: 'a, A: 'a> SetterOptic<'a, Q, S, S, A, A>
979		for AffineTraversalPrime<'a, PointerBrand, S, A>
980	where
981		PointerBrand: ToDynCloneFn,
982		Q: ToDynCloneFn,
983	{
984		#[document_signature]
985		#[document_parameters("The profunctor value to transform.")]
986		#[document_returns("The transformed profunctor value.")]
987		#[document_examples]
988		///
989		/// ```
990		/// use fp_library::{
991		/// 	brands::{
992		/// 		optics::*,
993		/// 		*,
994		/// 	},
995		/// 	classes::optics::*,
996		/// 	functions::*,
997		/// 	types::optics::*,
998		/// };
999		///
1000		/// let at: AffineTraversalPrime<RcBrand, (i32, String), i32> =
1001		/// 	AffineTraversalPrime::from_preview_set(|(x, _)| Some(x), |((_, s), x)| (x, s));
1002		///
1003		/// let f = lift_fn_new::<RcFnBrand, _, _>(|x: i32| x * 2);
1004		/// let modifier = <AffineTraversalPrime<RcBrand, (i32, String), i32> as SetterOptic<
1005		/// 	RcBrand,
1006		/// 	_,
1007		/// 	_,
1008		/// 	_,
1009		/// 	_,
1010		/// >>::evaluate(&at, f);
1011		/// assert_eq!(modifier((21, "hello".to_string())), (42, "hello".to_string()));
1012		/// ```
1013		fn evaluate(
1014			&self,
1015			pab: Apply!(<FnBrand<Q> as Kind!( type Of<'b, T: 'b, U: 'b>: 'b; )>::Of<'a, A, A>),
1016		) -> Apply!(<FnBrand<Q> as Kind!( type Of<'b, T: 'b, U: 'b>: 'b; )>::Of<'a, S, S>) {
1017			Optic::<FnBrand<Q>, S, S, A, A>::evaluate(self, pab)
1018		}
1019	}
1020}
1021pub use inner::*;