Skip to main content

fp_library/types/
step.rs

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