Skip to main content

fp_library/types/
step.rs

1//! Control type representing Loop/Done states for tail-recursive computations.
2//!
3//! Used by [`MonadRec`](crate::classes::monad_rec::MonadRec) to implement stack-safe tail recursion. [`Step::Loop`] continues iteration, while [`Step::Done`] terminates with a result.
4//!
5//! ### Examples
6//!
7//! ```
8//! use fp_library::types::*;
9//!
10//! // Count down from n to 0, accumulating the sum
11//! fn sum_to_zero(
12//! 	n: i32,
13//! 	acc: i32,
14//! ) -> Step<(i32, i32), i32> {
15//! 	if n <= 0 { Step::Done(acc) } else { Step::Loop((n - 1, acc + n)) }
16//! }
17//! ```
18
19#[fp_macros::document_module]
20mod inner {
21	use {
22		crate::{
23			Apply,
24			brands::{
25				StepBrand,
26				StepDoneAppliedBrand,
27				StepLoopAppliedBrand,
28			},
29			classes::{
30				Applicative,
31				ApplyFirst,
32				ApplySecond,
33				Bifoldable,
34				Bifunctor,
35				Bitraversable,
36				CloneableFn,
37				Foldable,
38				Functor,
39				Lift,
40				Monoid,
41				ParFoldable,
42				Pointed,
43				Semiapplicative,
44				Semimonad,
45				SendCloneableFn,
46				Traversable,
47			},
48			impl_kind,
49			kinds::*,
50		},
51		fp_macros::*,
52	};
53
54	/// Represents the result of a single step in a tail-recursive computation.
55	///
56	/// This type is fundamental to stack-safe recursion via `MonadRec`.
57	///
58	/// ### Higher-Kinded Type Representation
59	///
60	/// This type has multiple higher-kinded representations:
61	/// - [`StepBrand`](crate::brands::StepBrand): fully polymorphic over both loop and done types (bifunctor).
62	/// - [`StepLoopAppliedBrand<LoopType>`](crate::brands::StepLoopAppliedBrand): the loop type is fixed, polymorphic over the done type (functor over done).
63	/// - [`StepDoneAppliedBrand<DoneType>`](crate::brands::StepDoneAppliedBrand): the done type is fixed, polymorphic over the loop type (functor over loop).
64	///
65	/// ### Serialization
66	///
67	/// This type supports serialization and deserialization via [`serde`](https://serde.rs) when the `serde` feature is enabled.
68	#[document_type_parameters(
69		r#"The "loop" type - when we return `Loop(a)`, we continue with `a`."#,
70		r#"The "done" type - when we return `Done(b)`, we're finished."#
71	)]
72	///
73	/// ### Variants
74	///
75	/// * `Loop(A)`: Continue the loop with a new value.
76	/// * `Done(B)`: Finish the computation with a final value.
77	#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
78	#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
79	pub enum Step<A, B> {
80		/// Continue the loop with a new value
81		Loop(A),
82		/// Finish the computation with a final value
83		Done(B),
84	}
85
86	#[document_type_parameters(
87		r#"The "loop" type - when we return `Loop(a)`, we continue with `a`."#,
88		r#"The "done" type - when we return `Done(b)`, we're finished."#
89	)]
90	#[document_parameters("The step value.")]
91	impl<A, B> Step<A, B> {
92		/// Returns `true` if this is a `Loop` variant.
93		#[document_signature]
94		///
95		#[document_returns("`true` if the step is a loop, `false` otherwise.")]
96		///
97		#[inline]
98		#[document_examples]
99		///
100		/// ```
101		/// use fp_library::types::*;
102		///
103		/// let step: Step<i32, i32> = Step::Loop(1);
104		/// assert!(step.is_loop());
105		/// ```
106		pub fn is_loop(&self) -> bool {
107			matches!(self, Step::Loop(_))
108		}
109
110		/// Returns `true` if this is a `Done` variant.
111		#[document_signature]
112		///
113		#[document_returns("`true` if the step is done, `false` otherwise.")]
114		///
115		#[inline]
116		#[document_examples]
117		///
118		/// ```
119		/// use fp_library::types::*;
120		///
121		/// let step: Step<i32, i32> = Step::Done(1);
122		/// assert!(step.is_done());
123		/// ```
124		pub fn is_done(&self) -> bool {
125			matches!(self, Step::Done(_))
126		}
127
128		/// Maps a function over the `Loop` variant.
129		#[document_signature]
130		///
131		#[document_type_parameters("The new loop type.")]
132		///
133		#[document_parameters("The function to apply to the loop value.")]
134		///
135		#[document_returns("A new `Step` with the loop value transformed.")]
136		///
137		#[document_examples]
138		///
139		/// ```
140		/// use fp_library::types::*;
141		///
142		/// let step: Step<i32, i32> = Step::Loop(1);
143		/// let mapped = step.map_loop(|x| x + 1);
144		/// assert_eq!(mapped, Step::Loop(2));
145		/// ```
146		pub fn map_loop<C>(
147			self,
148			f: impl FnOnce(A) -> C,
149		) -> Step<C, B> {
150			match self {
151				Step::Loop(a) => Step::Loop(f(a)),
152				Step::Done(b) => Step::Done(b),
153			}
154		}
155
156		/// Maps a function over the `Done` variant.
157		#[document_signature]
158		///
159		#[document_type_parameters("The new done type.")]
160		///
161		#[document_parameters("The function to apply to the done value.")]
162		///
163		#[document_returns("A new `Step` with the done value transformed.")]
164		///
165		#[document_examples]
166		///
167		/// ```
168		/// use fp_library::types::*;
169		///
170		/// let step: Step<i32, i32> = Step::Done(1);
171		/// let mapped = step.map_done(|x| x + 1);
172		/// assert_eq!(mapped, Step::Done(2));
173		/// ```
174		pub fn map_done<C>(
175			self,
176			f: impl FnOnce(B) -> C,
177		) -> Step<A, C> {
178			match self {
179				Step::Loop(a) => Step::Loop(a),
180				Step::Done(b) => Step::Done(f(b)),
181			}
182		}
183
184		/// Applies functions to both variants (bifunctor map).
185		#[document_signature]
186		///
187		#[document_type_parameters("The new loop type.", "The new done type.")]
188		///
189		#[document_parameters(
190			"The function to apply to the loop value.",
191			"The function to apply to the done value."
192		)]
193		///
194		#[document_returns("A new `Step` with both values transformed.")]
195		#[document_examples]
196		///
197		/// ```
198		/// use fp_library::types::*;
199		///
200		/// let step: Step<i32, i32> = Step::Loop(1);
201		/// let mapped = step.bimap(|x| x + 1, |x| x * 2);
202		/// assert_eq!(mapped, Step::Loop(2));
203		/// ```
204		pub fn bimap<C, D>(
205			self,
206			f: impl FnOnce(A) -> C,
207			g: impl FnOnce(B) -> D,
208		) -> Step<C, D> {
209			match self {
210				Step::Loop(a) => Step::Loop(f(a)),
211				Step::Done(b) => Step::Done(g(b)),
212			}
213		}
214
215		/// Folds the step from right to left using two step functions.
216		///
217		/// See [`Bifoldable::bi_fold_right`] for the type class version.
218		#[document_signature]
219		///
220		#[document_type_parameters("The accumulator type.")]
221		///
222		#[document_parameters(
223			"The step function for the Loop variant.",
224			"The step function for the Done variant.",
225			"The initial accumulator."
226		)]
227		///
228		#[document_returns("The result of folding.")]
229		///
230		#[document_examples]
231		///
232		/// ```
233		/// use fp_library::types::*;
234		///
235		/// let x: Step<i32, i32> = Step::Loop(3);
236		/// assert_eq!(x.bi_fold_right(|a, acc| acc - a, |b, acc| acc + b, 10), 7);
237		/// ```
238		pub fn bi_fold_right<C>(
239			self,
240			f: impl FnOnce(A, C) -> C,
241			g: impl FnOnce(B, C) -> C,
242			z: C,
243		) -> C {
244			match self {
245				Step::Loop(a) => f(a, z),
246				Step::Done(b) => g(b, z),
247			}
248		}
249
250		/// Folds the step from left to right using two step functions.
251		///
252		/// See [`Bifoldable::bi_fold_left`] for the type class version.
253		#[document_signature]
254		///
255		#[document_type_parameters("The accumulator type.")]
256		///
257		#[document_parameters(
258			"The step function for the Loop variant.",
259			"The step function for the Done variant.",
260			"The initial accumulator."
261		)]
262		///
263		#[document_returns("The result of folding.")]
264		///
265		#[document_examples]
266		///
267		/// ```
268		/// use fp_library::types::*;
269		///
270		/// let x: Step<i32, i32> = Step::Done(5);
271		/// assert_eq!(x.bi_fold_left(|acc, a| acc - a, |acc, b| acc + b, 10), 15);
272		/// ```
273		pub fn bi_fold_left<C>(
274			self,
275			f: impl FnOnce(C, A) -> C,
276			g: impl FnOnce(C, B) -> C,
277			z: C,
278		) -> C {
279			match self {
280				Step::Loop(a) => f(z, a),
281				Step::Done(b) => g(z, b),
282			}
283		}
284
285		/// Maps the value to a monoid depending on the variant.
286		///
287		/// See [`Bifoldable::bi_fold_map`] for the type class version.
288		#[document_signature]
289		///
290		#[document_type_parameters("The monoid type.")]
291		///
292		#[document_parameters(
293			"The function mapping the Loop value to the monoid.",
294			"The function mapping the Done value to the monoid."
295		)]
296		///
297		#[document_returns("The monoid value.")]
298		///
299		#[document_examples]
300		///
301		/// ```
302		/// use fp_library::types::*;
303		///
304		/// let x: Step<i32, i32> = Step::Loop(3);
305		/// assert_eq!(x.bi_fold_map(|a: i32| a.to_string(), |b: i32| b.to_string()), "3");
306		/// ```
307		pub fn bi_fold_map<M>(
308			self,
309			f: impl FnOnce(A) -> M,
310			g: impl FnOnce(B) -> M,
311		) -> M {
312			match self {
313				Step::Loop(a) => f(a),
314				Step::Done(b) => g(b),
315			}
316		}
317
318		/// Folds the Done value, returning `initial` for Loop.
319		///
320		/// See [`Foldable::fold_right`] for the type class version
321		/// (via [`StepLoopAppliedBrand`]).
322		#[document_signature]
323		///
324		#[document_type_parameters("The accumulator type.")]
325		///
326		#[document_parameters(
327			"The function to apply to the Done value and the accumulator.",
328			"The initial accumulator."
329		)]
330		///
331		#[document_returns("The result of folding.")]
332		///
333		#[document_examples]
334		///
335		/// ```
336		/// use fp_library::types::*;
337		///
338		/// let x: Step<(), i32> = Step::Done(5);
339		/// assert_eq!(x.fold_right(|b, acc| b + acc, 10), 15);
340		/// ```
341		pub fn fold_right<C>(
342			self,
343			f: impl FnOnce(B, C) -> C,
344			initial: C,
345		) -> C {
346			match self {
347				Step::Loop(_) => initial,
348				Step::Done(b) => f(b, initial),
349			}
350		}
351
352		/// Folds the Done value from the left, returning `initial` for Loop.
353		///
354		/// See [`Foldable::fold_left`] for the type class version
355		/// (via [`StepLoopAppliedBrand`]).
356		#[document_signature]
357		///
358		#[document_type_parameters("The accumulator type.")]
359		///
360		#[document_parameters(
361			"The function to apply to the accumulator and the Done value.",
362			"The initial accumulator."
363		)]
364		///
365		#[document_returns("The result of folding.")]
366		///
367		#[document_examples]
368		///
369		/// ```
370		/// use fp_library::types::*;
371		///
372		/// let x: Step<(), i32> = Step::Done(5);
373		/// assert_eq!(x.fold_left(|acc, b| acc + b, 10), 15);
374		/// ```
375		pub fn fold_left<C>(
376			self,
377			f: impl FnOnce(C, B) -> C,
378			initial: C,
379		) -> C {
380			match self {
381				Step::Loop(_) => initial,
382				Step::Done(b) => f(initial, b),
383			}
384		}
385
386		/// Maps the Done value to a monoid, returning `M::empty()` for Loop.
387		///
388		/// See [`Foldable::fold_map`] for the type class version
389		/// (via [`StepLoopAppliedBrand`]).
390		#[document_signature]
391		///
392		#[document_type_parameters("The monoid type.")]
393		///
394		#[document_parameters("The mapping function.")]
395		///
396		#[document_returns("The monoid value.")]
397		///
398		#[document_examples]
399		///
400		/// ```
401		/// use fp_library::types::*;
402		///
403		/// let x: Step<(), i32> = Step::Done(5);
404		/// assert_eq!(x.fold_map(|b: i32| b.to_string()), "5".to_string());
405		/// ```
406		pub fn fold_map<M: Monoid>(
407			self,
408			f: impl FnOnce(B) -> M,
409		) -> M {
410			match self {
411				Step::Loop(_) => M::empty(),
412				Step::Done(b) => f(b),
413			}
414		}
415
416		/// Chains the Done value into a new computation, passing through Loop.
417		///
418		/// See [`Semimonad::bind`] for the type class version
419		/// (via [`StepLoopAppliedBrand`]).
420		#[document_signature]
421		///
422		#[document_type_parameters("The type of the resulting Done value.")]
423		///
424		#[document_parameters("The function to apply to the Done value.")]
425		///
426		#[document_returns("The result of the computation.")]
427		///
428		#[document_examples]
429		///
430		/// ```
431		/// use fp_library::types::*;
432		///
433		/// let x: Step<i32, i32> = Step::Done(5);
434		/// let y = x.bind(|b| Step::Done(b * 2));
435		/// assert_eq!(y, Step::Done(10));
436		/// ```
437		pub fn bind<C>(
438			self,
439			f: impl FnOnce(B) -> Step<A, C>,
440		) -> Step<A, C> {
441			match self {
442				Step::Loop(a) => Step::Loop(a),
443				Step::Done(b) => f(b),
444			}
445		}
446
447		/// Chains the Loop value into a new computation, passing through Done.
448		///
449		/// See [`Semimonad::bind`] for the type class version
450		/// (via [`StepDoneAppliedBrand`]).
451		#[document_signature]
452		///
453		#[document_type_parameters("The type of the resulting Loop value.")]
454		///
455		#[document_parameters("The function to apply to the Loop value.")]
456		///
457		#[document_returns("The result of the computation.")]
458		///
459		#[document_examples]
460		///
461		/// ```
462		/// use fp_library::types::*;
463		///
464		/// let x: Step<i32, i32> = Step::Loop(5);
465		/// let y = x.bind_loop(|a| Step::Loop(a * 2));
466		/// assert_eq!(y, Step::Loop(10));
467		/// ```
468		pub fn bind_loop<C>(
469			self,
470			f: impl FnOnce(A) -> Step<C, B>,
471		) -> Step<C, B> {
472			match self {
473				Step::Loop(a) => f(a),
474				Step::Done(b) => Step::Done(b),
475			}
476		}
477	}
478
479	#[document_type_parameters(
480		"The lifetime of the values.",
481		"The type of the Loop value.",
482		"The type of the Done value."
483	)]
484	#[document_parameters("The step instance.")]
485	impl<'a, A: 'a, B: 'a> Step<A, B> {
486		/// Traverses the step with two effectful functions.
487		///
488		/// See [`Bitraversable::bi_traverse`] for the type class version.
489		#[document_signature]
490		///
491		#[document_type_parameters(
492			"The output type for the Loop value.",
493			"The output type for the Done value.",
494			"The applicative context."
495		)]
496		///
497		#[document_parameters(
498			"The function for the Loop value.",
499			"The function for the Done value."
500		)]
501		///
502		#[document_returns("The transformed step wrapped in the applicative context.")]
503		///
504		#[document_examples]
505		///
506		/// ```
507		/// use fp_library::{
508		/// 	brands::*,
509		/// 	types::*,
510		/// };
511		///
512		/// let x: Step<i32, i32> = Step::Loop(3);
513		/// let y = x.bi_traverse::<_, _, OptionBrand>(|a| Some(a + 1), |b| Some(b * 2));
514		/// assert_eq!(y, Some(Step::Loop(4)));
515		/// ```
516		pub fn bi_traverse<C: 'a + Clone, D: 'a + Clone, F: Applicative>(
517			self,
518			f: impl Fn(A) -> Apply!(<F as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, C>) + 'a,
519			g: impl Fn(B) -> Apply!(<F as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, D>) + 'a,
520		) -> Apply!(<F as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, Step<C, D>>)
521		where
522			Step<C, D>: Clone, {
523			match self {
524				Step::Loop(a) => F::map(|c| Step::Loop(c), f(a)),
525				Step::Done(b) => F::map(|d| Step::Done(d), g(b)),
526			}
527		}
528	}
529
530	impl_kind! {
531		for StepBrand {
532			type Of<A, B> = Step<A, B>;
533		}
534	}
535
536	impl_kind! {
537		for StepBrand {
538			type Of<'a, A: 'a, B: 'a>: 'a = Step<A, B>;
539		}
540	}
541
542	impl Bifunctor for StepBrand {
543		/// Maps functions over the values in the step.
544		///
545		/// This method applies one function to the loop value and another to the done value.
546		#[document_signature]
547		///
548		#[document_type_parameters(
549			"The lifetime of the values.",
550			"The type of the loop value.",
551			"The type of the mapped loop value.",
552			"The type of the done value.",
553			"The type of the mapped done value."
554		)]
555		///
556		#[document_parameters(
557			"The function to apply to the loop value.",
558			"The function to apply to the done value.",
559			"The step to map over."
560		)]
561		///
562		#[document_returns("A new step containing the mapped values.")]
563		#[document_examples]
564		///
565		/// ```
566		/// use fp_library::{
567		/// 	brands::*,
568		/// 	classes::bifunctor::*,
569		/// 	functions::*,
570		/// 	types::*,
571		/// };
572		///
573		/// let x = Step::Loop(1);
574		/// assert_eq!(bimap::<StepBrand, _, _, _, _>(|a| a + 1, |b: i32| b * 2, x), Step::Loop(2));
575		/// ```
576		fn bimap<'a, A: 'a, B: 'a, C: 'a, D: 'a>(
577			f: impl Fn(A) -> B + 'a,
578			g: impl Fn(C) -> D + 'a,
579			p: Apply!(<Self as Kind!( type Of<'a, A: 'a, B: 'a>: 'a; )>::Of<'a, A, C>),
580		) -> Apply!(<Self as Kind!( type Of<'a, A: 'a, B: 'a>: 'a; )>::Of<'a, B, D>) {
581			p.bimap(f, g)
582		}
583	}
584
585	impl Bifoldable for StepBrand {
586		/// Folds the step from right to left using two step functions.
587		///
588		/// Applies `f` to the Loop value or `g` to the Done value.
589		#[document_signature]
590		///
591		#[document_type_parameters(
592			"The lifetime of the values.",
593			"The brand of the cloneable function to use.",
594			"The type of the Loop value.",
595			"The type of the Done value.",
596			"The accumulator type."
597		)]
598		///
599		#[document_parameters(
600			"The step function for the Loop variant.",
601			"The step function for the Done variant.",
602			"The initial accumulator.",
603			"The step to fold."
604		)]
605		///
606		#[document_returns("The folded result.")]
607		#[document_examples]
608		///
609		/// ```
610		/// use fp_library::{
611		/// 	brands::*,
612		/// 	functions::*,
613		/// 	types::*,
614		/// };
615		///
616		/// let x: Step<i32, i32> = Step::Loop(3);
617		/// assert_eq!(
618		/// 	bi_fold_right::<RcFnBrand, StepBrand, _, _, _>(|a, acc| acc - a, |b, acc| acc + b, 10, x,),
619		/// 	7
620		/// );
621		/// ```
622		fn bi_fold_right<'a, FnBrand: CloneableFn + 'a, A: 'a + Clone, B: 'a + Clone, C: 'a>(
623			f: impl Fn(A, C) -> C + 'a,
624			g: impl Fn(B, C) -> C + 'a,
625			z: C,
626			p: Apply!(<Self as Kind!( type Of<'a, A: 'a, B: 'a>: 'a; )>::Of<'a, A, B>),
627		) -> C {
628			p.bi_fold_right(f, g, z)
629		}
630
631		/// Folds the step from left to right using two step functions.
632		///
633		/// Applies `f` to the Loop value or `g` to the Done value.
634		#[document_signature]
635		///
636		#[document_type_parameters(
637			"The lifetime of the values.",
638			"The brand of the cloneable function to use.",
639			"The type of the Loop value.",
640			"The type of the Done value.",
641			"The accumulator type."
642		)]
643		///
644		#[document_parameters(
645			"The step function for the Loop variant.",
646			"The step function for the Done variant.",
647			"The initial accumulator.",
648			"The step to fold."
649		)]
650		///
651		#[document_returns("The folded result.")]
652		#[document_examples]
653		///
654		/// ```
655		/// use fp_library::{
656		/// 	brands::*,
657		/// 	functions::*,
658		/// 	types::*,
659		/// };
660		///
661		/// let x: Step<i32, i32> = Step::Done(5);
662		/// assert_eq!(
663		/// 	bi_fold_left::<RcFnBrand, StepBrand, _, _, _>(|acc, a| acc - a, |acc, b| acc + b, 10, x,),
664		/// 	15
665		/// );
666		/// ```
667		fn bi_fold_left<'a, FnBrand: CloneableFn + 'a, A: 'a + Clone, B: 'a + Clone, C: 'a>(
668			f: impl Fn(C, A) -> C + 'a,
669			g: impl Fn(C, B) -> C + 'a,
670			z: C,
671			p: Apply!(<Self as Kind!( type Of<'a, A: 'a, B: 'a>: 'a; )>::Of<'a, A, B>),
672		) -> C {
673			p.bi_fold_left(f, g, z)
674		}
675
676		/// Maps the value to a monoid depending on the variant.
677		///
678		/// Applies `f` if Loop, `g` if Done.
679		#[document_signature]
680		///
681		#[document_type_parameters(
682			"The lifetime of the values.",
683			"The brand of the cloneable function to use.",
684			"The type of the Loop value.",
685			"The type of the Done value.",
686			"The monoid type."
687		)]
688		///
689		#[document_parameters(
690			"The function mapping the Loop value to the monoid.",
691			"The function mapping the Done value to the monoid.",
692			"The step to fold."
693		)]
694		///
695		#[document_returns("The monoid value.")]
696		#[document_examples]
697		///
698		/// ```
699		/// use fp_library::{
700		/// 	brands::*,
701		/// 	functions::*,
702		/// 	types::*,
703		/// };
704		///
705		/// let x: Step<i32, i32> = Step::Loop(3);
706		/// assert_eq!(
707		/// 	bi_fold_map::<RcFnBrand, StepBrand, _, _, _>(
708		/// 		|a: i32| a.to_string(),
709		/// 		|b: i32| b.to_string(),
710		/// 		x,
711		/// 	),
712		/// 	"3".to_string()
713		/// );
714		/// ```
715		fn bi_fold_map<'a, FnBrand: CloneableFn + 'a, A: 'a + Clone, B: 'a + Clone, M>(
716			f: impl Fn(A) -> M + 'a,
717			g: impl Fn(B) -> M + 'a,
718			p: Apply!(<Self as Kind!( type Of<'a, A: 'a, B: 'a>: 'a; )>::Of<'a, A, B>),
719		) -> M
720		where
721			M: Monoid + 'a, {
722			p.bi_fold_map(f, g)
723		}
724	}
725
726	impl Bitraversable for StepBrand {
727		/// Traverses the step with two effectful functions.
728		///
729		/// Applies `f` to the Loop value or `g` to the Done value,
730		/// wrapping the result in the applicative context.
731		#[document_signature]
732		///
733		#[document_type_parameters(
734			"The lifetime of the values.",
735			"The type of the Loop value.",
736			"The type of the Done value.",
737			"The output type for Loop.",
738			"The output type for Done.",
739			"The applicative context."
740		)]
741		///
742		#[document_parameters(
743			"The function applied to the Loop value.",
744			"The function applied to the Done value.",
745			"The step to traverse."
746		)]
747		///
748		#[document_returns("The transformed step wrapped in the applicative context.")]
749		#[document_examples]
750		///
751		/// ```
752		/// use fp_library::{
753		/// 	brands::*,
754		/// 	functions::*,
755		/// 	types::*,
756		/// };
757		///
758		/// let x: Step<i32, i32> = Step::Loop(3);
759		/// assert_eq!(
760		/// 	bi_traverse::<StepBrand, _, _, _, _, OptionBrand>(
761		/// 		|a: i32| Some(a + 1),
762		/// 		|b: i32| Some(b * 2),
763		/// 		x,
764		/// 	),
765		/// 	Some(Step::Loop(4))
766		/// );
767		/// ```
768		fn bi_traverse<
769			'a,
770			A: 'a + Clone,
771			B: 'a + Clone,
772			C: 'a + Clone,
773			D: 'a + Clone,
774			F: Applicative,
775		>(
776			f: impl Fn(A) -> Apply!(<F as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, C>) + 'a,
777			g: impl Fn(B) -> Apply!(<F as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, D>) + 'a,
778			p: Apply!(<Self as Kind!( type Of<'a, A: 'a, B: 'a>: 'a; )>::Of<'a, A, B>),
779		) -> Apply!(<F as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, Apply!(<Self as Kind!( type Of<'a, A: 'a, B: 'a>: 'a; )>::Of<'a, C, D>)>)
780		{
781			p.bi_traverse::<C, D, F>(f, g)
782		}
783	}
784
785	// StepLoopAppliedBrand<LoopType> (Functor over B - Done)
786
787	impl_kind! {
788		impl<LoopType: 'static> for StepLoopAppliedBrand<LoopType> {
789			type Of<'a, B: 'a>: 'a = Step<LoopType, B>;
790		}
791	}
792
793	#[document_type_parameters("The loop type.")]
794	impl<LoopType: 'static> Functor for StepLoopAppliedBrand<LoopType> {
795		/// Maps a function over the done value in the step.
796		///
797		/// This method applies a function to the done value inside the step, producing a new step with the transformed done value. The loop value remains unchanged.
798		#[document_signature]
799		///
800		#[document_type_parameters(
801			"The lifetime of the values.",
802			"The type of the done value.",
803			"The type of the result of applying the function."
804		)]
805		///
806		#[document_parameters("The function to apply to the done value.", "The step to map over.")]
807		///
808		#[document_returns(
809			"A new step containing the result of applying the function to the done value."
810		)]
811		///
812		#[document_examples]
813		///
814		/// ```
815		/// use fp_library::{
816		/// 	brands::*,
817		/// 	functions::*,
818		/// 	types::*,
819		/// };
820		///
821		/// assert_eq!(
822		/// 	map::<StepLoopAppliedBrand<i32>, _, _>(|x: i32| x * 2, Step::<i32, i32>::Done(5)),
823		/// 	Step::Done(10)
824		/// );
825		/// ```
826		fn map<'a, A: 'a, B: 'a>(
827			func: impl Fn(A) -> B + 'a,
828			fa: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
829		) -> Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>) {
830			fa.map_done(func)
831		}
832	}
833
834	#[document_type_parameters("The loop type.")]
835	impl<LoopType: Clone + 'static> Lift for StepLoopAppliedBrand<LoopType> {
836		/// Lifts a binary function into the step context.
837		///
838		/// This method lifts a binary function to operate on values within the step context.
839		#[document_signature]
840		///
841		#[document_type_parameters(
842			"The lifetime of the values.",
843			"The type of the first value.",
844			"The type of the second value.",
845			"The type of the result."
846		)]
847		///
848		#[document_parameters(
849			"The binary function to apply.",
850			"The first step.",
851			"The second step."
852		)]
853		///
854		#[document_returns(
855			"`Done(f(a, b))` if both steps are `Done`, otherwise the first loop encountered."
856		)]
857		#[document_examples]
858		///
859		/// ```
860		/// use fp_library::{
861		/// 	brands::*,
862		/// 	functions::*,
863		/// 	types::*,
864		/// };
865		///
866		/// assert_eq!(
867		/// 	lift2::<StepLoopAppliedBrand<()>, _, _, _>(
868		/// 		|x: i32, y: i32| x + y,
869		/// 		Step::Done(1),
870		/// 		Step::Done(2)
871		/// 	),
872		/// 	Step::Done(3)
873		/// );
874		/// assert_eq!(
875		/// 	lift2::<StepLoopAppliedBrand<i32>, _, _, _>(
876		/// 		|x: i32, y: i32| x + y,
877		/// 		Step::Done(1),
878		/// 		Step::Loop(2)
879		/// 	),
880		/// 	Step::Loop(2)
881		/// );
882		/// ```
883		fn lift2<'a, A, B, C>(
884			func: impl Fn(A, B) -> C + 'a,
885			fa: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
886			fb: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>),
887		) -> Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, C>)
888		where
889			A: Clone + 'a,
890			B: Clone + 'a,
891			C: 'a, {
892			match (fa, fb) {
893				(Step::Done(a), Step::Done(b)) => Step::Done(func(a, b)),
894				(Step::Loop(e), _) => Step::Loop(e),
895				(_, Step::Loop(e)) => Step::Loop(e),
896			}
897		}
898	}
899
900	#[document_type_parameters("The loop type.")]
901	impl<LoopType: 'static> Pointed for StepLoopAppliedBrand<LoopType> {
902		/// Wraps a value in a step.
903		///
904		/// This method wraps a value in the `Done` variant of a `Step`.
905		#[document_signature]
906		///
907		#[document_type_parameters("The lifetime of the value.", "The type of the value to wrap.")]
908		///
909		#[document_parameters("The value to wrap.")]
910		///
911		#[document_returns("`Done(a)`.")]
912		///
913		#[document_examples]
914		///
915		/// ```
916		/// use fp_library::{
917		/// 	brands::*,
918		/// 	functions::*,
919		/// 	types::*,
920		/// };
921		///
922		/// assert_eq!(pure::<StepLoopAppliedBrand<()>, _>(5), Step::Done(5));
923		/// ```
924		fn pure<'a, A: 'a>(a: A) -> Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>) {
925			Step::Done(a)
926		}
927	}
928
929	#[document_type_parameters("The loop type.")]
930	impl<LoopType: Clone + 'static> ApplyFirst for StepLoopAppliedBrand<LoopType> {}
931
932	#[document_type_parameters("The loop type.")]
933	impl<LoopType: Clone + 'static> ApplySecond for StepLoopAppliedBrand<LoopType> {}
934
935	#[document_type_parameters("The loop type.")]
936	impl<LoopType: Clone + 'static> Semiapplicative for StepLoopAppliedBrand<LoopType> {
937		/// Applies a wrapped function to a wrapped value.
938		///
939		/// This method applies a function wrapped in a step to a value wrapped in a step.
940		#[document_signature]
941		///
942		#[document_type_parameters(
943			"The lifetime of the values.",
944			"The brand of the cloneable function wrapper.",
945			"The type of the input value.",
946			"The type of the output value."
947		)]
948		///
949		#[document_parameters(
950			"The step containing the function.",
951			"The step containing the value."
952		)]
953		///
954		#[document_returns(
955			"`Done(f(a))` if both are `Done`, otherwise the first loop encountered."
956		)]
957		#[document_examples]
958		///
959		/// ```
960		/// use fp_library::{
961		/// 	brands::*,
962		/// 	classes::*,
963		/// 	functions::*,
964		/// 	types::*,
965		/// };
966		///
967		/// let f: Step<_, _> = Step::Done(cloneable_fn_new::<RcFnBrand, _, _>(|x: i32| x * 2));
968		/// assert_eq!(
969		/// 	apply::<RcFnBrand, StepLoopAppliedBrand<()>, _, _>(f, Step::Done(5)),
970		/// 	Step::Done(10)
971		/// );
972		/// ```
973		fn apply<'a, FnBrand: 'a + CloneableFn, A: 'a + Clone, B: 'a>(
974			ff: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, <FnBrand as CloneableFn>::Of<'a, A, B>>),
975			fa: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
976		) -> Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>) {
977			match (ff, fa) {
978				(Step::Done(f), Step::Done(a)) => Step::Done(f(a)),
979				(Step::Loop(e), _) => Step::Loop(e),
980				(_, Step::Loop(e)) => Step::Loop(e),
981			}
982		}
983	}
984
985	#[document_type_parameters("The loop type.")]
986	impl<LoopType: Clone + 'static> Semimonad for StepLoopAppliedBrand<LoopType> {
987		/// Chains step computations.
988		///
989		/// This method chains two computations, where the second computation depends on the result of the first.
990		#[document_signature]
991		///
992		#[document_type_parameters(
993			"The lifetime of the values.",
994			"The type of the result of the first computation.",
995			"The type of the result of the second computation."
996		)]
997		///
998		#[document_parameters(
999			"The first step.",
1000			"The function to apply to the value inside the step."
1001		)]
1002		///
1003		#[document_returns(
1004			"The result of applying `f` to the value if `ma` is `Done`, otherwise the original loop."
1005		)]
1006		#[document_examples]
1007		///
1008		/// ```
1009		/// use fp_library::{
1010		/// 	brands::*,
1011		/// 	functions::*,
1012		/// 	types::*,
1013		/// };
1014		///
1015		/// assert_eq!(
1016		/// 	bind::<StepLoopAppliedBrand<()>, _, _>(Step::Done(5), |x| Step::Done(x * 2)),
1017		/// 	Step::Done(10)
1018		/// );
1019		/// ```
1020		fn bind<'a, A: 'a, B: 'a>(
1021			ma: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
1022			func: impl Fn(A) -> Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>) + 'a,
1023		) -> Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>) {
1024			ma.bind(func)
1025		}
1026	}
1027
1028	#[document_type_parameters("The loop type.")]
1029	impl<LoopType: 'static> Foldable for StepLoopAppliedBrand<LoopType> {
1030		/// Folds the step from the right.
1031		///
1032		/// This method performs a right-associative fold of the step.
1033		#[document_signature]
1034		///
1035		#[document_type_parameters(
1036			"The lifetime of the values.",
1037			"The brand of the cloneable function to use.",
1038			"The type of the elements in the structure.",
1039			"The type of the accumulator."
1040		)]
1041		///
1042		#[document_parameters("The folding function.", "The initial value.", "The step to fold.")]
1043		///
1044		#[document_returns("`func(a, initial)` if `fa` is `Done(a)`, otherwise `initial`.")]
1045		///
1046		#[document_examples]
1047		///
1048		/// ```
1049		/// use fp_library::{
1050		/// 	brands::*,
1051		/// 	functions::*,
1052		/// 	types::*,
1053		/// };
1054		///
1055		/// assert_eq!(
1056		/// 	fold_right::<RcFnBrand, StepLoopAppliedBrand<()>, _, _>(|x, acc| x + acc, 0, Step::Done(5)),
1057		/// 	5
1058		/// );
1059		/// assert_eq!(
1060		/// 	fold_right::<RcFnBrand, StepLoopAppliedBrand<i32>, _, _>(
1061		/// 		|x: i32, acc| x + acc,
1062		/// 		0,
1063		/// 		Step::Loop(1)
1064		/// 	),
1065		/// 	0
1066		/// );
1067		/// ```
1068		fn fold_right<'a, FnBrand, A: 'a, B: 'a>(
1069			func: impl Fn(A, B) -> B + 'a,
1070			initial: B,
1071			fa: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
1072		) -> B
1073		where
1074			FnBrand: CloneableFn + 'a, {
1075			fa.fold_right(func, initial)
1076		}
1077
1078		/// Folds the step from the left.
1079		///
1080		/// This method performs a left-associative fold of the step.
1081		#[document_signature]
1082		///
1083		#[document_type_parameters(
1084			"The lifetime of the values.",
1085			"The brand of the cloneable function to use.",
1086			"The type of the elements in the structure.",
1087			"The type of the accumulator."
1088		)]
1089		///
1090		#[document_parameters("The folding function.", "The initial value.", "The step to fold.")]
1091		///
1092		#[document_returns("`func(initial, a)` if `fa` is `Done(a)`, otherwise `initial`.")]
1093		///
1094		#[document_examples]
1095		///
1096		/// ```
1097		/// use fp_library::{
1098		/// 	brands::*,
1099		/// 	functions::*,
1100		/// 	types::*,
1101		/// };
1102		///
1103		/// assert_eq!(
1104		/// 	fold_left::<RcFnBrand, StepLoopAppliedBrand<()>, _, _>(|acc, x| acc + x, 0, Step::Done(5)),
1105		/// 	5
1106		/// );
1107		/// assert_eq!(
1108		/// 	fold_left::<RcFnBrand, StepLoopAppliedBrand<i32>, _, _>(
1109		/// 		|acc, x: i32| acc + x,
1110		/// 		0,
1111		/// 		Step::Loop(1)
1112		/// 	),
1113		/// 	0
1114		/// );
1115		/// ```
1116		fn fold_left<'a, FnBrand, A: 'a, B: 'a>(
1117			func: impl Fn(B, A) -> B + 'a,
1118			initial: B,
1119			fa: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
1120		) -> B
1121		where
1122			FnBrand: CloneableFn + 'a, {
1123			fa.fold_left(func, initial)
1124		}
1125
1126		/// Maps the value to a monoid and returns it.
1127		///
1128		/// This method maps the element of the step to a monoid and then returns it.
1129		#[document_signature]
1130		///
1131		#[document_type_parameters(
1132			"The lifetime of the values.",
1133			"The brand of the cloneable function to use.",
1134			"The type of the elements in the structure.",
1135			"The type of the monoid."
1136		)]
1137		///
1138		#[document_parameters("The mapping function.", "The step to fold.")]
1139		///
1140		#[document_returns("`func(a)` if `fa` is `Done(a)`, otherwise `M::empty()`.")]
1141		///
1142		#[document_examples]
1143		///
1144		/// ```
1145		/// use fp_library::{
1146		/// 	brands::*,
1147		/// 	functions::*,
1148		/// 	types::*,
1149		/// };
1150		///
1151		/// assert_eq!(
1152		/// 	fold_map::<RcFnBrand, StepLoopAppliedBrand<()>, _, _>(
1153		/// 		|x: i32| x.to_string(),
1154		/// 		Step::Done(5)
1155		/// 	),
1156		/// 	"5".to_string()
1157		/// );
1158		/// assert_eq!(
1159		/// 	fold_map::<RcFnBrand, StepLoopAppliedBrand<i32>, _, _>(
1160		/// 		|x: i32| x.to_string(),
1161		/// 		Step::Loop(1)
1162		/// 	),
1163		/// 	"".to_string()
1164		/// );
1165		/// ```
1166		fn fold_map<'a, FnBrand, A: 'a, M>(
1167			func: impl Fn(A) -> M + 'a,
1168			fa: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
1169		) -> M
1170		where
1171			M: Monoid + 'a,
1172			FnBrand: CloneableFn + 'a, {
1173			fa.fold_map(func)
1174		}
1175	}
1176
1177	#[document_type_parameters("The loop type.")]
1178	impl<LoopType: Clone + 'static> Traversable for StepLoopAppliedBrand<LoopType> {
1179		/// Traverses the step with an applicative function.
1180		///
1181		/// This method maps the element of the step to a computation, evaluates it, and combines the result into an applicative context.
1182		#[document_signature]
1183		///
1184		#[document_type_parameters(
1185			"The lifetime of the values.",
1186			"The type of the elements in the traversable structure.",
1187			"The type of the elements in the resulting traversable structure.",
1188			"The applicative context."
1189		)]
1190		///
1191		#[document_parameters("The function to apply.", "The step to traverse.")]
1192		///
1193		#[document_returns("The step wrapped in the applicative context.")]
1194		///
1195		#[document_examples]
1196		///
1197		/// ```
1198		/// use fp_library::{
1199		/// 	brands::*,
1200		/// 	functions::*,
1201		/// 	types::*,
1202		/// };
1203		///
1204		/// assert_eq!(
1205		/// 	traverse::<StepLoopAppliedBrand<()>, _, _, OptionBrand>(|x| Some(x * 2), Step::Done(5)),
1206		/// 	Some(Step::Done(10))
1207		/// );
1208		/// assert_eq!(
1209		/// 	traverse::<StepLoopAppliedBrand<i32>, _, _, OptionBrand>(
1210		/// 		|x: i32| Some(x * 2),
1211		/// 		Step::Loop(1)
1212		/// 	),
1213		/// 	Some(Step::Loop(1))
1214		/// );
1215		/// ```
1216		fn traverse<'a, A: 'a + Clone, B: 'a + Clone, F: Applicative>(
1217			func: impl Fn(A) -> Apply!(<F as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>) + 'a,
1218			ta: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
1219		) -> Apply!(<F as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>)>)
1220		where
1221			Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>): Clone, {
1222			match ta {
1223				Step::Done(a) => F::map(|b| Step::Done(b), func(a)),
1224				Step::Loop(e) => F::pure(Step::Loop(e)),
1225			}
1226		}
1227
1228		/// Sequences a step of applicative.
1229		///
1230		/// This method evaluates the computation inside the step and accumulates the result into an applicative context.
1231		#[document_signature]
1232		///
1233		#[document_type_parameters(
1234			"The lifetime of the values.",
1235			"The type of the elements in the traversable structure.",
1236			"The applicative context."
1237		)]
1238		///
1239		#[document_parameters("The step containing the applicative value.")]
1240		///
1241		#[document_returns("The step wrapped in the applicative context.")]
1242		///
1243		#[document_examples]
1244		///
1245		/// ```
1246		/// use fp_library::{
1247		/// 	brands::*,
1248		/// 	functions::*,
1249		/// 	types::*,
1250		/// };
1251		///
1252		/// assert_eq!(
1253		/// 	sequence::<StepLoopAppliedBrand<()>, _, OptionBrand>(Step::Done(Some(5))),
1254		/// 	Some(Step::Done(5))
1255		/// );
1256		/// assert_eq!(
1257		/// 	sequence::<StepLoopAppliedBrand<i32>, i32, OptionBrand>(Step::Loop::<i32, Option<i32>>(1)),
1258		/// 	Some(Step::Loop::<i32, i32>(1))
1259		/// );
1260		/// ```
1261		fn sequence<'a, A: 'a + Clone, F: Applicative>(
1262			ta: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, Apply!(<F as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>)>)
1263		) -> Apply!(<F as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>)>)
1264		where
1265			Apply!(<F as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>): Clone,
1266			Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>): Clone, {
1267			match ta {
1268				Step::Done(fa) => F::map(|a| Step::Done(a), fa),
1269				Step::Loop(e) => F::pure(Step::Loop(e)),
1270			}
1271		}
1272	}
1273
1274	#[document_type_parameters("The loop type.")]
1275	impl<LoopType: 'static> ParFoldable for StepLoopAppliedBrand<LoopType> {
1276		/// Maps the value to a monoid and returns it, or returns empty, in parallel.
1277		///
1278		/// This method maps the element of the step to a monoid and then returns it. The mapping operation may be executed in parallel.
1279		#[document_signature]
1280		///
1281		#[document_type_parameters(
1282			"The lifetime of the values.",
1283			"The brand of the cloneable function wrapper.",
1284			"The element type.",
1285			"The monoid type."
1286		)]
1287		///
1288		#[document_parameters(
1289			"The thread-safe function to map each element to a monoid.",
1290			"The step to fold."
1291		)]
1292		///
1293		#[document_returns("The combined monoid value.")]
1294		#[document_examples]
1295		///
1296		/// ```
1297		/// use fp_library::{
1298		/// 	brands::*,
1299		/// 	classes::*,
1300		/// 	functions::*,
1301		/// 	types::*,
1302		/// };
1303		///
1304		/// let x: Step<i32, i32> = Step::Done(5);
1305		/// let f = send_cloneable_fn_new::<ArcFnBrand, _, _>(|x: i32| x.to_string());
1306		/// assert_eq!(
1307		/// 	par_fold_map::<ArcFnBrand, StepLoopAppliedBrand<i32>, _, _>(f.clone(), x),
1308		/// 	"5".to_string()
1309		/// );
1310		///
1311		/// let x_loop: Step<i32, i32> = Step::Loop(1);
1312		/// assert_eq!(
1313		/// 	par_fold_map::<ArcFnBrand, StepLoopAppliedBrand<i32>, _, _>(f, x_loop),
1314		/// 	"".to_string()
1315		/// );
1316		/// ```
1317		fn par_fold_map<'a, FnBrand, A, M>(
1318			func: <FnBrand as SendCloneableFn>::SendOf<'a, A, M>,
1319			fa: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
1320		) -> M
1321		where
1322			FnBrand: 'a + SendCloneableFn,
1323			A: 'a + Clone + Send + Sync,
1324			M: Monoid + Send + Sync + 'a, {
1325			match fa {
1326				Step::Done(a) => func(a),
1327				Step::Loop(_) => M::empty(),
1328			}
1329		}
1330
1331		/// Folds the step from the right in parallel.
1332		///
1333		/// This method folds the step by applying a function from right to left, potentially in parallel.
1334		#[document_signature]
1335		///
1336		#[document_type_parameters(
1337			"The lifetime of the values.",
1338			"The brand of the cloneable function wrapper.",
1339			"The element type.",
1340			"The accumulator type."
1341		)]
1342		///
1343		#[document_parameters(
1344			"The thread-safe function to apply to each element and the accumulator.",
1345			"The initial value.",
1346			"The step to fold."
1347		)]
1348		///
1349		#[document_returns("The final accumulator value.")]
1350		#[document_examples]
1351		///
1352		/// ```
1353		/// use fp_library::{
1354		/// 	brands::*,
1355		/// 	classes::*,
1356		/// 	functions::*,
1357		/// 	types::*,
1358		/// };
1359		///
1360		/// let x: Step<i32, i32> = Step::Done(5);
1361		/// let f = send_cloneable_fn_new::<ArcFnBrand, _, _>(|(a, b): (i32, i32)| a + b);
1362		/// assert_eq!(par_fold_right::<ArcFnBrand, StepLoopAppliedBrand<i32>, _, _>(f.clone(), 10, x), 15);
1363		///
1364		/// let x_loop: Step<i32, i32> = Step::Loop(1);
1365		/// assert_eq!(par_fold_right::<ArcFnBrand, StepLoopAppliedBrand<i32>, _, _>(f, 10, x_loop), 10);
1366		/// ```
1367		fn par_fold_right<'a, FnBrand, A, B>(
1368			func: <FnBrand as SendCloneableFn>::SendOf<'a, (A, B), B>,
1369			initial: B,
1370			fa: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
1371		) -> B
1372		where
1373			FnBrand: 'a + SendCloneableFn,
1374			A: 'a + Clone + Send + Sync,
1375			B: Send + Sync + 'a, {
1376			match fa {
1377				Step::Done(a) => func((a, initial)),
1378				Step::Loop(_) => initial,
1379			}
1380		}
1381	}
1382
1383	// StepDoneAppliedBrand<DoneType> (Functor over A - Loop)
1384
1385	impl_kind! {
1386		impl<DoneType: 'static> for StepDoneAppliedBrand<DoneType> {
1387			type Of<'a, A: 'a>: 'a = Step<A, DoneType>;
1388		}
1389	}
1390
1391	#[document_type_parameters("The done type.")]
1392	impl<DoneType: 'static> Functor for StepDoneAppliedBrand<DoneType> {
1393		/// Maps a function over the loop value in the step.
1394		///
1395		/// This method applies a function to the loop value inside the step, producing a new step with the transformed loop value. The done value remains unchanged.
1396		#[document_signature]
1397		///
1398		#[document_type_parameters(
1399			"The lifetime of the values.",
1400			"The type of the loop value.",
1401			"The type of the result of applying the function."
1402		)]
1403		///
1404		#[document_parameters("The function to apply to the loop value.", "The step to map over.")]
1405		///
1406		#[document_returns(
1407			"A new step containing the result of applying the function to the loop value."
1408		)]
1409		///
1410		#[document_examples]
1411		///
1412		/// ```
1413		/// use fp_library::{
1414		/// 	brands::*,
1415		/// 	functions::*,
1416		/// 	types::*,
1417		/// };
1418		///
1419		/// assert_eq!(
1420		/// 	map::<StepDoneAppliedBrand<i32>, _, _>(|x: i32| x * 2, Step::<i32, i32>::Loop(5)),
1421		/// 	Step::Loop(10)
1422		/// );
1423		/// ```
1424		fn map<'a, A: 'a, B: 'a>(
1425			func: impl Fn(A) -> B + 'a,
1426			fa: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
1427		) -> Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>) {
1428			fa.map_loop(func)
1429		}
1430	}
1431
1432	#[document_type_parameters("The done type.")]
1433	impl<DoneType: Clone + 'static> Lift for StepDoneAppliedBrand<DoneType> {
1434		/// Lifts a binary function into the step context (over loop).
1435		///
1436		/// This method lifts a binary function to operate on loop values within the step context.
1437		#[document_signature]
1438		///
1439		#[document_type_parameters(
1440			"The lifetime of the values.",
1441			"The type of the first loop value.",
1442			"The type of the second loop value.",
1443			"The type of the result loop value."
1444		)]
1445		///
1446		#[document_parameters(
1447			"The binary function to apply to the loops.",
1448			"The first step.",
1449			"The second step."
1450		)]
1451		///
1452		#[document_returns(
1453			"`Loop(f(a, b))` if both steps are `Loop`, otherwise the first done encountered."
1454		)]
1455		#[document_examples]
1456		///
1457		/// ```
1458		/// use fp_library::{
1459		/// 	brands::*,
1460		/// 	functions::*,
1461		/// 	types::*,
1462		/// };
1463		///
1464		/// assert_eq!(
1465		/// 	lift2::<StepDoneAppliedBrand<i32>, _, _, _>(
1466		/// 		|x: i32, y: i32| x + y,
1467		/// 		Step::Loop(1),
1468		/// 		Step::Loop(2)
1469		/// 	),
1470		/// 	Step::Loop(3)
1471		/// );
1472		/// assert_eq!(
1473		/// 	lift2::<StepDoneAppliedBrand<i32>, _, _, _>(
1474		/// 		|x: i32, y: i32| x + y,
1475		/// 		Step::Loop(1),
1476		/// 		Step::Done(2)
1477		/// 	),
1478		/// 	Step::Done(2)
1479		/// );
1480		/// ```
1481		fn lift2<'a, A, B, C>(
1482			func: impl Fn(A, B) -> C + 'a,
1483			fa: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
1484			fb: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>),
1485		) -> Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, C>)
1486		where
1487			A: Clone + 'a,
1488			B: Clone + 'a,
1489			C: 'a, {
1490			match (fa, fb) {
1491				(Step::Loop(a), Step::Loop(b)) => Step::Loop(func(a, b)),
1492				(Step::Done(t), _) => Step::Done(t),
1493				(_, Step::Done(t)) => Step::Done(t),
1494			}
1495		}
1496	}
1497
1498	#[document_type_parameters("The done type.")]
1499	impl<DoneType: 'static> Pointed for StepDoneAppliedBrand<DoneType> {
1500		/// Wraps a value in a step (as loop).
1501		///
1502		/// This method wraps a value in the `Loop` variant of a `Step`.
1503		#[document_signature]
1504		///
1505		#[document_type_parameters("The lifetime of the value.", "The type of the value to wrap.")]
1506		///
1507		#[document_parameters("The value to wrap.")]
1508		///
1509		#[document_returns("`Loop(a)`.")]
1510		///
1511		#[document_examples]
1512		///
1513		/// ```
1514		/// use fp_library::{
1515		/// 	brands::*,
1516		/// 	functions::*,
1517		/// 	types::*,
1518		/// };
1519		///
1520		/// assert_eq!(pure::<StepDoneAppliedBrand<()>, _>(5), Step::Loop(5));
1521		/// ```
1522		fn pure<'a, A: 'a>(a: A) -> Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>) {
1523			Step::Loop(a)
1524		}
1525	}
1526
1527	#[document_type_parameters("The done type.")]
1528	impl<DoneType: Clone + 'static> ApplyFirst for StepDoneAppliedBrand<DoneType> {}
1529
1530	#[document_type_parameters("The done type.")]
1531	impl<DoneType: Clone + 'static> ApplySecond for StepDoneAppliedBrand<DoneType> {}
1532
1533	#[document_type_parameters("The done type.")]
1534	impl<DoneType: Clone + 'static> Semiapplicative for StepDoneAppliedBrand<DoneType> {
1535		/// Applies a wrapped function to a wrapped value (over loop).
1536		///
1537		/// This method applies a function wrapped in a step (as loop) to a value wrapped in a step (as loop).
1538		#[document_signature]
1539		///
1540		#[document_type_parameters(
1541			"The lifetime of the values.",
1542			"The brand of the cloneable function wrapper.",
1543			"The type of the input value.",
1544			"The type of the output value."
1545		)]
1546		///
1547		#[document_parameters(
1548			"The step containing the function (in Loop).",
1549			"The step containing the value (in Loop)."
1550		)]
1551		///
1552		#[document_returns(
1553			"`Loop(f(a))` if both are `Loop`, otherwise the first done encountered."
1554		)]
1555		#[document_examples]
1556		///
1557		/// ```
1558		/// use fp_library::{
1559		/// 	brands::*,
1560		/// 	classes::*,
1561		/// 	functions::*,
1562		/// 	types::*,
1563		/// };
1564		///
1565		/// let f: Step<_, ()> = Step::Loop(cloneable_fn_new::<RcFnBrand, _, _>(|x: i32| x * 2));
1566		/// assert_eq!(
1567		/// 	apply::<RcFnBrand, StepDoneAppliedBrand<()>, _, _>(f, Step::Loop(5)),
1568		/// 	Step::Loop(10)
1569		/// );
1570		/// ```
1571		fn apply<'a, FnBrand: 'a + CloneableFn, A: 'a + Clone, B: 'a>(
1572			ff: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, <FnBrand as CloneableFn>::Of<'a, A, B>>),
1573			fa: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
1574		) -> Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>) {
1575			match (ff, fa) {
1576				(Step::Loop(f), Step::Loop(a)) => Step::Loop(f(a)),
1577				(Step::Done(t), _) => Step::Done(t),
1578				(_, Step::Done(t)) => Step::Done(t),
1579			}
1580		}
1581	}
1582
1583	#[document_type_parameters("The done type.")]
1584	impl<DoneType: Clone + 'static> Semimonad for StepDoneAppliedBrand<DoneType> {
1585		/// Chains step computations (over loop).
1586		///
1587		/// This method chains two computations, where the second computation depends on the result of the first (over loop).
1588		#[document_signature]
1589		///
1590		#[document_type_parameters(
1591			"The lifetime of the values.",
1592			"The type of the result of the first computation.",
1593			"The type of the result of the second computation."
1594		)]
1595		///
1596		#[document_parameters("The first step.", "The function to apply to the loop value.")]
1597		///
1598		#[document_returns(
1599			"The result of applying `f` to the loop if `ma` is `Loop`, otherwise the original done."
1600		)]
1601		///
1602		#[document_examples]
1603		///
1604		/// ```
1605		/// use fp_library::{
1606		/// 	brands::*,
1607		/// 	functions::*,
1608		/// 	types::*,
1609		/// };
1610		///
1611		/// assert_eq!(
1612		/// 	bind::<StepDoneAppliedBrand<()>, _, _>(Step::Loop(5), |x| Step::Loop(x * 2)),
1613		/// 	Step::Loop(10)
1614		/// );
1615		/// ```
1616		fn bind<'a, A: 'a, B: 'a>(
1617			ma: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
1618			func: impl Fn(A) -> Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>) + 'a,
1619		) -> Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>) {
1620			ma.bind_loop(func)
1621		}
1622	}
1623
1624	#[document_type_parameters("The done type.")]
1625	impl<DoneType: 'static> Foldable for StepDoneAppliedBrand<DoneType> {
1626		/// Folds the step from the right (over loop).
1627		///
1628		/// This method performs a right-associative fold of the step (over loop).
1629		#[document_signature]
1630		///
1631		#[document_type_parameters(
1632			"The lifetime of the values.",
1633			"The brand of the cloneable function to use.",
1634			"The type of the elements in the structure.",
1635			"The type of the accumulator."
1636		)]
1637		///
1638		#[document_parameters("The folding function.", "The initial value.", "The step to fold.")]
1639		///
1640		#[document_returns("`func(a, initial)` if `fa` is `Loop(a)`, otherwise `initial`.")]
1641		///
1642		#[document_examples]
1643		///
1644		/// ```
1645		/// use fp_library::{
1646		/// 	brands::*,
1647		/// 	functions::*,
1648		/// 	types::*,
1649		/// };
1650		///
1651		/// assert_eq!(
1652		/// 	fold_right::<RcFnBrand, StepDoneAppliedBrand<i32>, _, _>(
1653		/// 		|x: i32, acc| x + acc,
1654		/// 		0,
1655		/// 		Step::Loop(1)
1656		/// 	),
1657		/// 	1
1658		/// );
1659		/// assert_eq!(
1660		/// 	fold_right::<RcFnBrand, StepDoneAppliedBrand<()>, _, _>(
1661		/// 		|x: i32, acc| x + acc,
1662		/// 		0,
1663		/// 		Step::Done(())
1664		/// 	),
1665		/// 	0
1666		/// );
1667		/// ```
1668		fn fold_right<'a, FnBrand, A: 'a, B: 'a>(
1669			func: impl Fn(A, B) -> B + 'a,
1670			initial: B,
1671			fa: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
1672		) -> B
1673		where
1674			FnBrand: CloneableFn + 'a, {
1675			match fa {
1676				Step::Loop(e) => func(e, initial),
1677				Step::Done(_) => initial,
1678			}
1679		}
1680
1681		/// Folds the step from the left (over loop).
1682		///
1683		/// This method performs a left-associative fold of the step (over loop).
1684		#[document_signature]
1685		///
1686		#[document_type_parameters(
1687			"The lifetime of the values.",
1688			"The brand of the cloneable function to use.",
1689			"The type of the elements in the structure.",
1690			"The type of the accumulator."
1691		)]
1692		///
1693		#[document_parameters("The folding function.", "The initial value.", "The step to fold.")]
1694		///
1695		#[document_returns("`func(initial, a)` if `fa` is `Loop(a)`, otherwise `initial`.")]
1696		///
1697		#[document_examples]
1698		///
1699		/// ```
1700		/// use fp_library::{
1701		/// 	brands::*,
1702		/// 	functions::*,
1703		/// 	types::*,
1704		/// };
1705		///
1706		/// assert_eq!(
1707		/// 	fold_left::<RcFnBrand, StepDoneAppliedBrand<()>, _, _>(
1708		/// 		|acc, x: i32| acc + x,
1709		/// 		0,
1710		/// 		Step::Loop(5)
1711		/// 	),
1712		/// 	5
1713		/// );
1714		/// assert_eq!(
1715		/// 	fold_left::<RcFnBrand, StepDoneAppliedBrand<i32>, _, _>(
1716		/// 		|acc, x: i32| acc + x,
1717		/// 		0,
1718		/// 		Step::Done(1)
1719		/// 	),
1720		/// 	0
1721		/// );
1722		/// ```
1723		fn fold_left<'a, FnBrand, A: 'a, B: 'a>(
1724			func: impl Fn(B, A) -> B + 'a,
1725			initial: B,
1726			fa: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
1727		) -> B
1728		where
1729			FnBrand: CloneableFn + 'a, {
1730			match fa {
1731				Step::Loop(e) => func(initial, e),
1732				Step::Done(_) => initial,
1733			}
1734		}
1735
1736		/// Maps the value to a monoid and returns it (over loop).
1737		///
1738		/// This method maps the element of the step to a monoid and then returns it (over loop).
1739		#[document_signature]
1740		///
1741		#[document_type_parameters(
1742			"The lifetime of the values.",
1743			"The brand of the cloneable function to use.",
1744			"The type of the elements in the structure.",
1745			"The type of the monoid."
1746		)]
1747		///
1748		#[document_parameters("The mapping function.", "The step to fold.")]
1749		///
1750		#[document_returns("`func(a)` if `fa` is `Loop(a)`, otherwise `M::empty()`.")]
1751		///
1752		#[document_examples]
1753		///
1754		/// ```
1755		/// use fp_library::{
1756		/// 	brands::*,
1757		/// 	functions::*,
1758		/// 	types::*,
1759		/// };
1760		///
1761		/// assert_eq!(
1762		/// 	fold_map::<RcFnBrand, StepDoneAppliedBrand<()>, _, _>(
1763		/// 		|x: i32| x.to_string(),
1764		/// 		Step::Loop(5)
1765		/// 	),
1766		/// 	"5".to_string()
1767		/// );
1768		/// assert_eq!(
1769		/// 	fold_map::<RcFnBrand, StepDoneAppliedBrand<i32>, _, _>(
1770		/// 		|x: i32| x.to_string(),
1771		/// 		Step::Done(1)
1772		/// 	),
1773		/// 	"".to_string()
1774		/// );
1775		/// ```
1776		fn fold_map<'a, FnBrand, A: 'a, M>(
1777			func: impl Fn(A) -> M + 'a,
1778			fa: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
1779		) -> M
1780		where
1781			M: Monoid + 'a,
1782			FnBrand: CloneableFn + 'a, {
1783			match fa {
1784				Step::Loop(e) => func(e),
1785				Step::Done(_) => M::empty(),
1786			}
1787		}
1788	}
1789
1790	#[document_type_parameters("The done type.")]
1791	impl<DoneType: Clone + 'static> Traversable for StepDoneAppliedBrand<DoneType> {
1792		/// Traverses the step with an applicative function (over loop).
1793		///
1794		/// This method maps the element of the step to a computation, evaluates it, and combines the result into an applicative context (over loop).
1795		#[document_signature]
1796		///
1797		#[document_type_parameters(
1798			"The lifetime of the values.",
1799			"The type of the elements in the traversable structure.",
1800			"The type of the elements in the resulting traversable structure.",
1801			"The applicative context."
1802		)]
1803		///
1804		#[document_parameters("The function to apply.", "The step to traverse.")]
1805		///
1806		#[document_returns("The step wrapped in the applicative context.")]
1807		///
1808		#[document_examples]
1809		///
1810		/// ```
1811		/// use fp_library::{
1812		/// 	brands::*,
1813		/// 	functions::*,
1814		/// 	types::*,
1815		/// };
1816		///
1817		/// assert_eq!(
1818		/// 	traverse::<StepDoneAppliedBrand<()>, _, _, OptionBrand>(|x| Some(x * 2), Step::Loop(5)),
1819		/// 	Some(Step::Loop(10))
1820		/// );
1821		/// assert_eq!(
1822		/// 	traverse::<StepDoneAppliedBrand<i32>, _, _, OptionBrand>(
1823		/// 		|x: i32| Some(x * 2),
1824		/// 		Step::Done(1)
1825		/// 	),
1826		/// 	Some(Step::Done(1))
1827		/// );
1828		/// ```
1829		fn traverse<'a, A: 'a + Clone, B: 'a + Clone, F: Applicative>(
1830			func: impl Fn(A) -> Apply!(<F as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>) + 'a,
1831			ta: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
1832		) -> Apply!(<F as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>)>)
1833		where
1834			Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>): Clone, {
1835			match ta {
1836				Step::Loop(e) => F::map(|b| Step::Loop(b), func(e)),
1837				Step::Done(t) => F::pure(Step::Done(t)),
1838			}
1839		}
1840
1841		/// Sequences a step of applicative (over loop).
1842		///
1843		/// This method evaluates the computation inside the step and accumulates the result into an applicative context (over loop).
1844		#[document_signature]
1845		///
1846		#[document_type_parameters(
1847			"The lifetime of the values.",
1848			"The type of the elements in the traversable structure.",
1849			"The applicative context."
1850		)]
1851		///
1852		#[document_parameters("The step containing the applicative value.")]
1853		///
1854		#[document_returns("The step wrapped in the applicative context.")]
1855		///
1856		#[document_examples]
1857		///
1858		/// ```
1859		/// use fp_library::{
1860		/// 	brands::*,
1861		/// 	functions::*,
1862		/// 	types::*,
1863		/// };
1864		///
1865		/// assert_eq!(
1866		/// 	sequence::<StepDoneAppliedBrand<()>, _, OptionBrand>(Step::Loop(Some(5))),
1867		/// 	Some(Step::Loop(5))
1868		/// );
1869		/// assert_eq!(
1870		/// 	sequence::<StepDoneAppliedBrand<i32>, i32, OptionBrand>(Step::Done::<Option<i32>, _>(1)),
1871		/// 	Some(Step::Done::<i32, i32>(1))
1872		/// );
1873		/// ```
1874		fn sequence<'a, A: 'a + Clone, F: Applicative>(
1875			ta: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, Apply!(<F as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>)>)
1876		) -> Apply!(<F as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>)>)
1877		where
1878			Apply!(<F as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>): Clone,
1879			Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>): Clone, {
1880			match ta {
1881				Step::Loop(fe) => F::map(|e| Step::Loop(e), fe),
1882				Step::Done(t) => F::pure(Step::Done(t)),
1883			}
1884		}
1885	}
1886
1887	#[document_type_parameters("The done type.")]
1888	impl<DoneType: 'static> ParFoldable for StepDoneAppliedBrand<DoneType> {
1889		/// Maps the value to a monoid and returns it, or returns empty, in parallel (over loop).
1890		///
1891		/// This method maps the element of the step to a monoid and then returns it (over loop). The mapping operation may be executed in parallel.
1892		#[document_signature]
1893		///
1894		#[document_type_parameters(
1895			"The lifetime of the values.",
1896			"The brand of the cloneable function wrapper.",
1897			"The element type.",
1898			"The monoid type."
1899		)]
1900		///
1901		#[document_parameters(
1902			"The thread-safe function to map each element to a monoid.",
1903			"The step to fold."
1904		)]
1905		///
1906		#[document_returns("The combined monoid value.")]
1907		#[document_examples]
1908		///
1909		/// ```
1910		/// use fp_library::{
1911		/// 	brands::*,
1912		/// 	classes::*,
1913		/// 	functions::*,
1914		/// 	types::*,
1915		/// };
1916		///
1917		/// let x: Step<i32, i32> = Step::Loop(5);
1918		/// let f = send_cloneable_fn_new::<ArcFnBrand, _, _>(|x: i32| x.to_string());
1919		/// assert_eq!(
1920		/// 	par_fold_map::<ArcFnBrand, StepDoneAppliedBrand<i32>, _, _>(f.clone(), x),
1921		/// 	"5".to_string()
1922		/// );
1923		///
1924		/// let x_done: Step<i32, i32> = Step::Done(1);
1925		/// assert_eq!(
1926		/// 	par_fold_map::<ArcFnBrand, StepDoneAppliedBrand<i32>, _, _>(f, x_done),
1927		/// 	"".to_string()
1928		/// );
1929		/// ```
1930		fn par_fold_map<'a, FnBrand, A, M>(
1931			func: <FnBrand as SendCloneableFn>::SendOf<'a, A, M>,
1932			fa: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
1933		) -> M
1934		where
1935			FnBrand: 'a + SendCloneableFn,
1936			A: 'a + Clone + Send + Sync,
1937			M: Monoid + Send + Sync + 'a, {
1938			match fa {
1939				Step::Loop(e) => func(e),
1940				Step::Done(_) => M::empty(),
1941			}
1942		}
1943
1944		/// Folds the step from the right in parallel (over loop).
1945		///
1946		/// This method folds the step by applying a function from right to left, potentially in parallel (over loop).
1947		#[document_signature]
1948		///
1949		#[document_type_parameters(
1950			"The lifetime of the values.",
1951			"The brand of the cloneable function wrapper.",
1952			"The element type.",
1953			"The accumulator type."
1954		)]
1955		///
1956		#[document_parameters(
1957			"The thread-safe function to apply to each element and the accumulator.",
1958			"The initial value.",
1959			"The step to fold."
1960		)]
1961		///
1962		#[document_returns("The final accumulator value.")]
1963		#[document_examples]
1964		///
1965		/// ```
1966		/// use fp_library::{
1967		/// 	brands::*,
1968		/// 	classes::*,
1969		/// 	functions::*,
1970		/// 	types::*,
1971		/// };
1972		///
1973		/// let x: Step<i32, i32> = Step::Loop(5);
1974		/// let f = send_cloneable_fn_new::<ArcFnBrand, _, _>(|(a, b): (i32, i32)| a + b);
1975		/// assert_eq!(par_fold_right::<ArcFnBrand, StepDoneAppliedBrand<i32>, _, _>(f.clone(), 10, x), 15);
1976		///
1977		/// let x_done: Step<i32, i32> = Step::Done(1);
1978		/// assert_eq!(par_fold_right::<ArcFnBrand, StepDoneAppliedBrand<i32>, _, _>(f, 10, x_done), 10);
1979		/// ```
1980		fn par_fold_right<'a, FnBrand, A, B>(
1981			func: <FnBrand as SendCloneableFn>::SendOf<'a, (A, B), B>,
1982			initial: B,
1983			fa: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
1984		) -> B
1985		where
1986			FnBrand: 'a + SendCloneableFn,
1987			A: 'a + Clone + Send + Sync,
1988			B: Send + Sync + 'a, {
1989			match fa {
1990				Step::Loop(e) => func((e, initial)),
1991				Step::Done(_) => initial,
1992			}
1993		}
1994	}
1995}
1996pub use inner::*;
1997
1998#[cfg(test)]
1999mod tests {
2000	use {
2001		super::*,
2002		crate::{
2003			brands::*,
2004			classes::{
2005				bifunctor::*,
2006				foldable::*,
2007				functor::*,
2008				lift::*,
2009				par_foldable::*,
2010				pointed::*,
2011				semiapplicative::*,
2012				semimonad::*,
2013				traversable::*,
2014			},
2015			functions::*,
2016		},
2017		quickcheck::{
2018			Arbitrary,
2019			Gen,
2020		},
2021		quickcheck_macros::quickcheck,
2022	};
2023
2024	impl<A: Arbitrary, B: Arbitrary> Arbitrary for Step<A, B> {
2025		fn arbitrary(g: &mut Gen) -> Self {
2026			if bool::arbitrary(g) {
2027				Step::Loop(A::arbitrary(g))
2028			} else {
2029				Step::Done(B::arbitrary(g))
2030			}
2031		}
2032	}
2033
2034	/// Tests the `is_loop` method.
2035	///
2036	/// Verifies that `is_loop` returns true for `Loop` variants and false for `Done` variants.
2037	#[test]
2038	fn test_is_loop() {
2039		let step: Step<i32, i32> = Step::Loop(1);
2040		assert!(step.is_loop());
2041		assert!(!step.is_done());
2042	}
2043
2044	/// Tests the `is_done` method.
2045	///
2046	/// Verifies that `is_done` returns true for `Done` variants and false for `Loop` variants.
2047	#[test]
2048	fn test_is_done() {
2049		let step: Step<i32, i32> = Step::Done(1);
2050		assert!(step.is_done());
2051		assert!(!step.is_loop());
2052	}
2053
2054	/// Tests the `map_loop` method.
2055	///
2056	/// Verifies that `map_loop` transforms the value inside a `Loop` variant and leaves a `Done` variant unchanged.
2057	#[test]
2058	fn test_map_loop() {
2059		let step: Step<i32, i32> = Step::Loop(1);
2060		let mapped = step.map_loop(|x| x + 1);
2061		assert_eq!(mapped, Step::Loop(2));
2062
2063		let done: Step<i32, i32> = Step::Done(1);
2064		let mapped_done = done.map_loop(|x| x + 1);
2065		assert_eq!(mapped_done, Step::Done(1));
2066	}
2067
2068	/// Tests the `map_done` method.
2069	///
2070	/// Verifies that `map_done` transforms the value inside a `Done` variant and leaves a `Loop` variant unchanged.
2071	#[test]
2072	fn test_map_done() {
2073		let step: Step<i32, i32> = Step::Done(1);
2074		let mapped = step.map_done(|x| x + 1);
2075		assert_eq!(mapped, Step::Done(2));
2076
2077		let loop_step: Step<i32, i32> = Step::Loop(1);
2078		let mapped_loop = loop_step.map_done(|x| x + 1);
2079		assert_eq!(mapped_loop, Step::Loop(1));
2080	}
2081
2082	/// Tests the `bimap` method.
2083	///
2084	/// Verifies that `bimap` transforms the value inside both `Loop` and `Done` variants using the appropriate function.
2085	#[test]
2086	fn test_bimap() {
2087		let step: Step<i32, i32> = Step::Loop(1);
2088		let mapped = step.bimap(|x| x + 1, |x| x * 2);
2089		assert_eq!(mapped, Step::Loop(2));
2090
2091		let done: Step<i32, i32> = Step::Done(1);
2092		let mapped_done = done.bimap(|x| x + 1, |x| x * 2);
2093		assert_eq!(mapped_done, Step::Done(2));
2094	}
2095
2096	/// Tests `Functor` implementation for `StepLoopAppliedBrand`.
2097	#[test]
2098	fn test_functor_step_with_loop() {
2099		let step: Step<i32, i32> = Step::Done(5);
2100		assert_eq!(map::<StepLoopAppliedBrand<_>, _, _>(|x: i32| x * 2, step), Step::Done(10));
2101
2102		let loop_step: Step<i32, i32> = Step::Loop(5);
2103		assert_eq!(map::<StepLoopAppliedBrand<_>, _, _>(|x: i32| x * 2, loop_step), Step::Loop(5));
2104	}
2105
2106	/// Tests `Functor` implementation for `StepDoneAppliedBrand`.
2107	#[test]
2108	fn test_functor_step_with_done() {
2109		let step: Step<i32, i32> = Step::Loop(5);
2110		assert_eq!(map::<StepDoneAppliedBrand<_>, _, _>(|x: i32| x * 2, step), Step::Loop(10));
2111
2112		let done_step: Step<i32, i32> = Step::Done(5);
2113		assert_eq!(map::<StepDoneAppliedBrand<_>, _, _>(|x: i32| x * 2, done_step), Step::Done(5));
2114	}
2115
2116	/// Tests `Bifunctor` implementation for `StepBrand`.
2117	#[test]
2118	fn test_bifunctor_step() {
2119		let step: Step<i32, i32> = Step::Loop(5);
2120		assert_eq!(bimap::<StepBrand, _, _, _, _>(|a| a + 1, |b| b * 2, step), Step::Loop(6));
2121
2122		let done: Step<i32, i32> = Step::Done(5);
2123		assert_eq!(bimap::<StepBrand, _, _, _, _>(|a| a + 1, |b| b * 2, done), Step::Done(10));
2124	}
2125
2126	// Functor Laws for StepLoopAppliedBrand
2127
2128	#[quickcheck]
2129	fn functor_identity_step_with_loop(x: Step<i32, i32>) -> bool {
2130		map::<StepLoopAppliedBrand<i32>, _, _>(identity, x) == x
2131	}
2132
2133	#[quickcheck]
2134	fn functor_composition_step_with_loop(x: Step<i32, i32>) -> bool {
2135		let f = |x: i32| x.wrapping_add(1);
2136		let g = |x: i32| x.wrapping_mul(2);
2137		map::<StepLoopAppliedBrand<i32>, _, _>(compose(f, g), x)
2138			== map::<StepLoopAppliedBrand<i32>, _, _>(
2139				f,
2140				map::<StepLoopAppliedBrand<i32>, _, _>(g, x),
2141			)
2142	}
2143
2144	// Functor Laws for StepDoneAppliedBrand
2145
2146	#[quickcheck]
2147	fn functor_identity_step_with_done(x: Step<i32, i32>) -> bool {
2148		map::<StepDoneAppliedBrand<i32>, _, _>(identity, x) == x
2149	}
2150
2151	#[quickcheck]
2152	fn functor_composition_step_with_done(x: Step<i32, i32>) -> bool {
2153		let f = |x: i32| x.wrapping_add(1);
2154		let g = |x: i32| x.wrapping_mul(2);
2155		map::<StepDoneAppliedBrand<i32>, _, _>(compose(f, g), x)
2156			== map::<StepDoneAppliedBrand<i32>, _, _>(
2157				f,
2158				map::<StepDoneAppliedBrand<i32>, _, _>(g, x),
2159			)
2160	}
2161
2162	// Bifunctor Laws for StepBrand
2163
2164	#[quickcheck]
2165	fn bifunctor_identity_step(x: Step<i32, i32>) -> bool {
2166		bimap::<StepBrand, _, _, _, _>(identity, identity, x) == x
2167	}
2168
2169	#[quickcheck]
2170	fn bifunctor_composition_step(x: Step<i32, i32>) -> bool {
2171		let f = |x: i32| x.wrapping_add(1);
2172		let g = |x: i32| x.wrapping_mul(2);
2173		let h = |x: i32| x.wrapping_sub(1);
2174		let i = |x: i32| if x == 0 { 0 } else { x.wrapping_div(2) };
2175
2176		bimap::<StepBrand, _, _, _, _>(compose(f, g), compose(h, i), x)
2177			== bimap::<StepBrand, _, _, _, _>(f, h, bimap::<StepBrand, _, _, _, _>(g, i, x))
2178	}
2179
2180	// Lift Tests
2181
2182	/// Tests the `lift2` function for `StepLoopAppliedBrand`.
2183	///
2184	/// Verifies that `lift2` correctly combines two `Step` values using a binary function,
2185	/// handling `Done` and `Loop` variants according to the `Lift` implementation.
2186	#[test]
2187	fn test_lift2_step_with_loop() {
2188		let s1: Step<i32, i32> = Step::Done(1);
2189		let s2: Step<i32, i32> = Step::Done(2);
2190		let s3: Step<i32, i32> = Step::Loop(3);
2191
2192		assert_eq!(
2193			lift2::<StepLoopAppliedBrand<i32>, _, _, _>(|x, y| x + y, s1, s2),
2194			Step::Done(3)
2195		);
2196		assert_eq!(
2197			lift2::<StepLoopAppliedBrand<i32>, _, _, _>(|x, y| x + y, s1, s3),
2198			Step::Loop(3)
2199		);
2200	}
2201
2202	/// Tests the `lift2` function for `StepDoneAppliedBrand`.
2203	///
2204	/// Verifies that `lift2` correctly combines two `Step` values using a binary function,
2205	/// handling `Done` and `Loop` variants according to the `Lift` implementation.
2206	#[test]
2207	fn test_lift2_step_with_done() {
2208		let s1: Step<i32, i32> = Step::Loop(1);
2209		let s2: Step<i32, i32> = Step::Loop(2);
2210		let s3: Step<i32, i32> = Step::Done(3);
2211
2212		assert_eq!(
2213			lift2::<StepDoneAppliedBrand<i32>, _, _, _>(|x, y| x + y, s1, s2),
2214			Step::Loop(3)
2215		);
2216		assert_eq!(
2217			lift2::<StepDoneAppliedBrand<i32>, _, _, _>(|x, y| x + y, s1, s3),
2218			Step::Done(3)
2219		);
2220	}
2221
2222	// Pointed Tests
2223
2224	/// Tests the `pure` function for `StepLoopAppliedBrand`.
2225	///
2226	/// Verifies that `pure` wraps a value into a `Step::Done` variant.
2227	#[test]
2228	fn test_pointed_step_with_loop() {
2229		assert_eq!(pure::<StepLoopAppliedBrand<()>, _>(5), Step::Done(5));
2230	}
2231
2232	/// Tests the `pure` function for `StepDoneAppliedBrand`.
2233	///
2234	/// Verifies that `pure` wraps a value into a `Step::Loop` variant.
2235	#[test]
2236	fn test_pointed_step_with_done() {
2237		assert_eq!(pure::<StepDoneAppliedBrand<()>, _>(5), Step::Loop(5));
2238	}
2239
2240	// Semiapplicative Tests
2241
2242	/// Tests the `apply` function for `StepLoopAppliedBrand`.
2243	///
2244	/// Verifies that `apply` correctly applies a wrapped function to a wrapped value,
2245	/// handling `Done` and `Loop` variants.
2246	#[test]
2247	fn test_apply_step_with_loop() {
2248		let f =
2249			pure::<StepLoopAppliedBrand<()>, _>(cloneable_fn_new::<RcFnBrand, _, _>(|x: i32| {
2250				x * 2
2251			}));
2252		let x = pure::<StepLoopAppliedBrand<()>, _>(5);
2253		assert_eq!(apply::<RcFnBrand, StepLoopAppliedBrand<()>, _, _>(f, x), Step::Done(10));
2254
2255		let loop_step: Step<i32, _> = Step::Loop(1);
2256		let f_loop =
2257			pure::<StepLoopAppliedBrand<i32>, _>(cloneable_fn_new::<RcFnBrand, _, _>(|x: i32| {
2258				x * 2
2259			}));
2260		assert_eq!(
2261			apply::<RcFnBrand, StepLoopAppliedBrand<i32>, _, _>(f_loop, loop_step),
2262			Step::Loop(1)
2263		);
2264	}
2265
2266	/// Tests the `apply` function for `StepDoneAppliedBrand`.
2267	///
2268	/// Verifies that `apply` correctly applies a wrapped function to a wrapped value,
2269	/// handling `Done` and `Loop` variants.
2270	#[test]
2271	fn test_apply_step_with_done() {
2272		let f =
2273			pure::<StepDoneAppliedBrand<()>, _>(cloneable_fn_new::<RcFnBrand, _, _>(|x: i32| {
2274				x * 2
2275			}));
2276		let x = pure::<StepDoneAppliedBrand<()>, _>(5);
2277		assert_eq!(apply::<RcFnBrand, StepDoneAppliedBrand<()>, _, _>(f, x), Step::Loop(10));
2278
2279		let done_step: Step<_, i32> = Step::Done(1);
2280		let f_done =
2281			pure::<StepDoneAppliedBrand<i32>, _>(cloneable_fn_new::<RcFnBrand, _, _>(|x: i32| {
2282				x * 2
2283			}));
2284		assert_eq!(
2285			apply::<RcFnBrand, StepDoneAppliedBrand<i32>, _, _>(f_done, done_step),
2286			Step::Done(1)
2287		);
2288	}
2289
2290	// Semimonad Tests
2291
2292	/// Tests the `bind` function for `StepLoopAppliedBrand`.
2293	///
2294	/// Verifies that `bind` correctly chains computations, handling `Done` and `Loop` variants.
2295	#[test]
2296	fn test_bind_step_with_loop() {
2297		let x = pure::<StepLoopAppliedBrand<()>, _>(5);
2298		assert_eq!(
2299			bind::<StepLoopAppliedBrand<()>, _, _>(x, |i| pure::<StepLoopAppliedBrand<()>, _>(
2300				i * 2
2301			)),
2302			Step::Done(10)
2303		);
2304
2305		let loop_step: Step<i32, i32> = Step::Loop(1);
2306		assert_eq!(
2307			bind::<StepLoopAppliedBrand<i32>, _, _>(loop_step, |i| pure::<
2308				StepLoopAppliedBrand<i32>,
2309				_,
2310			>(i * 2)),
2311			Step::Loop(1)
2312		);
2313	}
2314
2315	/// Tests the `bind` function for `StepDoneAppliedBrand`.
2316	///
2317	/// Verifies that `bind` correctly chains computations, handling `Done` and `Loop` variants.
2318	#[test]
2319	fn test_bind_step_with_done() {
2320		let x = pure::<StepDoneAppliedBrand<()>, _>(5);
2321		assert_eq!(
2322			bind::<StepDoneAppliedBrand<()>, _, _>(x, |i| pure::<StepDoneAppliedBrand<()>, _>(
2323				i * 2
2324			)),
2325			Step::Loop(10)
2326		);
2327
2328		let done_step: Step<i32, i32> = Step::Done(1);
2329		assert_eq!(
2330			bind::<StepDoneAppliedBrand<i32>, _, _>(done_step, |i| pure::<
2331				StepDoneAppliedBrand<i32>,
2332				_,
2333			>(i * 2)),
2334			Step::Done(1)
2335		);
2336	}
2337
2338	// Foldable Tests
2339
2340	/// Tests `Foldable` methods for `StepLoopAppliedBrand`.
2341	///
2342	/// Verifies `fold_right`, `fold_left`, and `fold_map` behavior for `Done` and `Loop` variants.
2343	#[test]
2344	fn test_foldable_step_with_loop() {
2345		let x = pure::<StepLoopAppliedBrand<()>, _>(5);
2346		assert_eq!(
2347			fold_right::<RcFnBrand, StepLoopAppliedBrand<()>, _, _>(|a, b| a + b, 10, x),
2348			15
2349		);
2350		assert_eq!(fold_left::<RcFnBrand, StepLoopAppliedBrand<()>, _, _>(|b, a| b + a, 10, x), 15);
2351		assert_eq!(
2352			fold_map::<RcFnBrand, StepLoopAppliedBrand<()>, _, _>(|a: i32| a.to_string(), x),
2353			"5"
2354		);
2355
2356		let loop_step: Step<i32, i32> = Step::Loop(1);
2357		assert_eq!(
2358			fold_right::<RcFnBrand, StepLoopAppliedBrand<i32>, _, _>(|a, b| a + b, 10, loop_step),
2359			10
2360		);
2361	}
2362
2363	/// Tests `Foldable` methods for `StepDoneAppliedBrand`.
2364	///
2365	/// Verifies `fold_right`, `fold_left`, and `fold_map` behavior for `Done` and `Loop` variants.
2366	#[test]
2367	fn test_foldable_step_with_done() {
2368		let x = pure::<StepDoneAppliedBrand<()>, _>(5);
2369		assert_eq!(
2370			fold_right::<RcFnBrand, StepDoneAppliedBrand<()>, _, _>(|a, b| a + b, 10, x),
2371			15
2372		);
2373		assert_eq!(fold_left::<RcFnBrand, StepDoneAppliedBrand<()>, _, _>(|b, a| b + a, 10, x), 15);
2374		assert_eq!(
2375			fold_map::<RcFnBrand, StepDoneAppliedBrand<()>, _, _>(|a: i32| a.to_string(), x),
2376			"5"
2377		);
2378
2379		let done_step: Step<i32, i32> = Step::Done(1);
2380		assert_eq!(
2381			fold_right::<RcFnBrand, StepDoneAppliedBrand<i32>, _, _>(|a, b| a + b, 10, done_step),
2382			10
2383		);
2384	}
2385
2386	// Traversable Tests
2387
2388	/// Tests the `traverse` function for `StepLoopAppliedBrand`.
2389	///
2390	/// Verifies that `traverse` correctly maps and sequences effects over `Step`.
2391	#[test]
2392	fn test_traversable_step_with_loop() {
2393		let x = pure::<StepLoopAppliedBrand<()>, _>(5);
2394		assert_eq!(
2395			traverse::<StepLoopAppliedBrand<()>, _, _, OptionBrand>(|a| Some(a * 2), x),
2396			Some(Step::Done(10))
2397		);
2398
2399		let loop_step: Step<i32, i32> = Step::Loop(1);
2400		assert_eq!(
2401			traverse::<StepLoopAppliedBrand<i32>, _, _, OptionBrand>(|a| Some(a * 2), loop_step),
2402			Some(Step::Loop(1))
2403		);
2404	}
2405
2406	/// Tests the `traverse` function for `StepDoneAppliedBrand`.
2407	///
2408	/// Verifies that `traverse` correctly maps and sequences effects over `Step`.
2409	#[test]
2410	fn test_traversable_step_with_done() {
2411		let x = pure::<StepDoneAppliedBrand<()>, _>(5);
2412		assert_eq!(
2413			traverse::<StepDoneAppliedBrand<()>, _, _, OptionBrand>(|a| Some(a * 2), x),
2414			Some(Step::Loop(10))
2415		);
2416
2417		let done_step: Step<i32, i32> = Step::Done(1);
2418		assert_eq!(
2419			traverse::<StepDoneAppliedBrand<i32>, _, _, OptionBrand>(|a| Some(a * 2), done_step),
2420			Some(Step::Done(1))
2421		);
2422	}
2423
2424	// ParFoldable Tests
2425
2426	/// Tests `par_fold_map` for `StepLoopAppliedBrand`.
2427	///
2428	/// Verifies parallel folding behavior (conceptually, as it delegates to sequential for simple types).
2429	#[test]
2430	fn test_par_foldable_step_with_loop() {
2431		let x = pure::<StepLoopAppliedBrand<()>, _>(5);
2432		let f = send_cloneable_fn_new::<ArcFnBrand, _, _>(|a: i32| a.to_string());
2433		assert_eq!(par_fold_map::<ArcFnBrand, StepLoopAppliedBrand<()>, _, _>(f, x), "5");
2434	}
2435
2436	/// Tests `par_fold_map` for `StepDoneAppliedBrand`.
2437	///
2438	/// Verifies parallel folding behavior.
2439	#[test]
2440	fn test_par_foldable_step_with_done() {
2441		let x = pure::<StepDoneAppliedBrand<()>, _>(5);
2442		let f = send_cloneable_fn_new::<ArcFnBrand, _, _>(|a: i32| a.to_string());
2443		assert_eq!(par_fold_map::<ArcFnBrand, StepDoneAppliedBrand<()>, _, _>(f, x), "5");
2444	}
2445
2446	// Monad Laws for StepLoopAppliedBrand
2447
2448	/// Verifies the Left Identity law for `StepLoopAppliedBrand` Monad.
2449	#[quickcheck]
2450	fn monad_left_identity_step_with_loop(a: i32) -> bool {
2451		let f = |x: i32| pure::<StepLoopAppliedBrand<i32>, _>(x.wrapping_mul(2));
2452		bind::<StepLoopAppliedBrand<i32>, _, _>(pure::<StepLoopAppliedBrand<i32>, _>(a), f) == f(a)
2453	}
2454
2455	/// Verifies the Right Identity law for `StepLoopAppliedBrand` Monad.
2456	#[quickcheck]
2457	fn monad_right_identity_step_with_loop(x: Step<i32, i32>) -> bool {
2458		bind::<StepLoopAppliedBrand<i32>, _, _>(x, pure::<StepLoopAppliedBrand<i32>, _>) == x
2459	}
2460
2461	/// Verifies the Associativity law for `StepLoopAppliedBrand` Monad.
2462	#[quickcheck]
2463	fn monad_associativity_step_with_loop(x: Step<i32, i32>) -> bool {
2464		let f = |x: i32| pure::<StepLoopAppliedBrand<i32>, _>(x.wrapping_mul(2));
2465		let g = |x: i32| pure::<StepLoopAppliedBrand<i32>, _>(x.wrapping_add(1));
2466		bind::<StepLoopAppliedBrand<i32>, _, _>(bind::<StepLoopAppliedBrand<i32>, _, _>(x, f), g)
2467			== bind::<StepLoopAppliedBrand<i32>, _, _>(x, |a| {
2468				bind::<StepLoopAppliedBrand<i32>, _, _>(f(a), g)
2469			})
2470	}
2471
2472	// Monad Laws for StepDoneAppliedBrand
2473
2474	/// Verifies the Left Identity law for `StepDoneAppliedBrand` Monad.
2475	#[quickcheck]
2476	fn monad_left_identity_step_with_done(a: i32) -> bool {
2477		let f = |x: i32| pure::<StepDoneAppliedBrand<i32>, _>(x.wrapping_mul(2));
2478		bind::<StepDoneAppliedBrand<i32>, _, _>(pure::<StepDoneAppliedBrand<i32>, _>(a), f) == f(a)
2479	}
2480
2481	/// Verifies the Right Identity law for `StepDoneAppliedBrand` Monad.
2482	#[quickcheck]
2483	fn monad_right_identity_step_with_done(x: Step<i32, i32>) -> bool {
2484		bind::<StepDoneAppliedBrand<i32>, _, _>(x, pure::<StepDoneAppliedBrand<i32>, _>) == x
2485	}
2486
2487	/// Verifies the Associativity law for `StepDoneAppliedBrand` Monad.
2488	#[quickcheck]
2489	fn monad_associativity_step_with_done(x: Step<i32, i32>) -> bool {
2490		let f = |x: i32| pure::<StepDoneAppliedBrand<i32>, _>(x.wrapping_mul(2));
2491		let g = |x: i32| pure::<StepDoneAppliedBrand<i32>, _>(x.wrapping_add(1));
2492		bind::<StepDoneAppliedBrand<i32>, _, _>(bind::<StepDoneAppliedBrand<i32>, _, _>(x, f), g)
2493			== bind::<StepDoneAppliedBrand<i32>, _, _>(x, |a| {
2494				bind::<StepDoneAppliedBrand<i32>, _, _>(f(a), g)
2495			})
2496	}
2497}