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