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