Skip to main content

fp_library/types/
step.rs

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