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