1#[fp_macros::document_module]
6mod inner {
7 use {
8 crate::{
9 Apply,
10 brands::IdentityBrand,
11 classes::*,
12 dispatch::Ref,
13 impl_kind,
14 kinds::*,
15 },
16 core::ops::ControlFlow,
17 fp_macros::*,
18 };
19
20 #[document_type_parameters("The type of the wrapped value.")]
34 #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
36 #[derive(Clone, Copy, Debug, Default, Eq, Hash, Ord, PartialEq, PartialOrd)]
37 pub struct Identity<A>(
38 pub A,
40 );
41
42 impl_kind! {
43 for IdentityBrand {
44 type Of<'a, A: 'a>: 'a = Identity<A>;
45 }
46 }
47
48 #[document_type_parameters("The type of the wrapped value.")]
49 #[document_parameters("The identity instance.")]
50 impl<A> Identity<A> {
51 #[document_signature]
56 #[document_type_parameters("The type of the result of applying the function.")]
58 #[document_parameters("The function to apply.")]
60 #[document_returns("A new identity containing the result of applying the function.")]
62 #[document_examples]
64 pub fn map<B>(
73 self,
74 f: impl FnOnce(A) -> B,
75 ) -> Identity<B> {
76 Identity(f(self.0))
77 }
78
79 #[document_signature]
83 #[document_type_parameters(
85 "The type of the other identity's value.",
86 "The return type of the function."
87 )]
88 #[document_parameters("The other identity.", "The binary function to apply.")]
90 #[document_returns("A new identity containing the result of applying the function.")]
92 #[document_examples]
94 pub fn lift2<B, C>(
104 self,
105 other: Identity<B>,
106 f: impl FnOnce(A, B) -> C,
107 ) -> Identity<C> {
108 Identity(f(self.0, other.0))
109 }
110
111 #[document_signature]
115 #[document_type_parameters("The return type of the wrapped function.")]
117 #[document_parameters("The identity containing the function.")]
119 #[document_returns("A new identity containing the result.")]
121 #[document_examples]
123 pub fn apply<B>(
133 self,
134 ff: Identity<impl FnOnce(A) -> B>,
135 ) -> Identity<B> {
136 Identity(ff.0(self.0))
137 }
138
139 #[document_signature]
144 #[document_type_parameters("The type of the result of the chained computation.")]
146 #[document_parameters("The function to apply to the value inside the identity.")]
148 #[document_returns("The result of applying `f` to the value.")]
150 #[document_examples]
152 pub fn bind<B>(
161 self,
162 f: impl FnOnce(A) -> Identity<B>,
163 ) -> Identity<B> {
164 f(self.0)
165 }
166
167 #[document_signature]
171 #[document_type_parameters("The type of the accumulator.")]
173 #[document_parameters(
175 "The function to apply to the element and the accumulator.",
176 "The initial value of the accumulator."
177 )]
178 #[document_returns("The final accumulator value.")]
180 #[document_examples]
182 pub fn fold_right<B>(
191 self,
192 f: impl FnOnce(A, B) -> B,
193 initial: B,
194 ) -> B {
195 f(self.0, initial)
196 }
197
198 #[document_signature]
202 #[document_type_parameters("The type of the accumulator.")]
204 #[document_parameters(
206 "The function to apply to the accumulator and the element.",
207 "The initial value of the accumulator."
208 )]
209 #[document_returns("The final accumulator value.")]
211 #[document_examples]
213 pub fn fold_left<B>(
222 self,
223 f: impl FnOnce(B, A) -> B,
224 initial: B,
225 ) -> B {
226 f(initial, self.0)
227 }
228
229 #[document_signature]
233 #[document_type_parameters("The monoid type.")]
235 #[document_parameters("The mapping function.")]
237 #[document_returns("The monoid value.")]
239 #[document_examples]
241 pub fn fold_map<M>(
250 self,
251 f: impl FnOnce(A) -> M,
252 ) -> M {
253 f(self.0)
254 }
255 }
256
257 #[document_type_parameters("The lifetime of the values.", "The type of the wrapped value.")]
258 #[document_parameters("The identity instance.")]
259 impl<'a, A: 'a> Identity<A> {
260 #[document_signature]
264 #[document_type_parameters(
266 "The type of the elements in the resulting identity.",
267 "The applicative context."
268 )]
269 #[document_parameters(
271 "The function to apply, returning a value in an applicative context."
272 )]
273 #[document_returns("The identity wrapped in the applicative context.")]
275 #[document_examples]
277 pub fn traverse<B: 'a + Clone, F: Applicative>(
289 self,
290 f: impl Fn(A) -> Apply!(<F as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>) + 'a,
291 ) -> Apply!(<F as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, Identity<B>>)
292 where
293 Identity<B>: Clone, {
294 F::map(|b| Identity(b), f(self.0))
295 }
296
297 #[document_signature]
301 #[document_type_parameters(
303 "The inner type wrapped in the applicative context.",
304 "The applicative context."
305 )]
306 #[document_returns("The identity wrapped in the applicative context.")]
308 #[document_examples]
310 pub fn sequence<InnerA: 'a + Clone, F: Applicative>(
322 self
323 ) -> Apply!(<F as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, Identity<InnerA>>)
324 where
325 A: Into<Apply!(<F as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, InnerA>)>,
326 Identity<InnerA>: Clone, {
327 F::map(|a| Identity(a), self.0.into())
328 }
329 }
330
331 impl Functor for IdentityBrand {
332 #[document_signature]
336 #[document_type_parameters(
338 "The lifetime of the value.",
339 "The type of the value inside the identity.",
340 "The type of the result of applying the function."
341 )]
342 #[document_parameters("The function to apply.", "The identity to map over.")]
344 #[document_returns("A new identity containing the result of applying the function.")]
346 #[document_examples]
348 fn map<'a, A: 'a, B: 'a>(
361 func: impl Fn(A) -> B + 'a,
362 fa: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
363 ) -> Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>) {
364 fa.map(func)
365 }
366 }
367
368 impl Lift for IdentityBrand {
369 #[document_signature]
373 #[document_type_parameters(
375 "The lifetime of the values.",
376 "The type of the first identity's value.",
377 "The type of the second identity's value.",
378 "The return type of the function."
379 )]
380 #[document_parameters(
382 "The binary function to apply.",
383 "The first identity.",
384 "The second identity."
385 )]
386 #[document_returns("A new identity containing the result of applying the function.")]
388 #[document_examples]
389 fn lift2<'a, A, B, C>(
403 func: impl Fn(A, B) -> C + 'a,
404 fa: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
405 fb: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>),
406 ) -> Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, C>)
407 where
408 A: 'a,
409 B: 'a,
410 C: 'a, {
411 fa.lift2(fb, func)
412 }
413 }
414
415 impl Pointed for IdentityBrand {
416 #[document_signature]
420 #[document_type_parameters("The lifetime of the value.", "The type of the value to wrap.")]
422 #[document_parameters("The value to wrap.")]
424 #[document_returns("An identity containing the value.")]
426 #[document_examples]
428 fn pure<'a, A: 'a>(a: A) -> Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>) {
440 Identity(a) }
442 }
443
444 impl ApplyFirst for IdentityBrand {}
445 impl ApplySecond for IdentityBrand {}
446
447 impl Semiapplicative for IdentityBrand {
448 #[document_signature]
452 #[document_type_parameters(
454 "The lifetime of the values.",
455 "The brand of the cloneable function wrapper.",
456 "The type of the input value.",
457 "The type of the output value."
458 )]
459 #[document_parameters(
461 "The identity containing the function.",
462 "The identity containing the value."
463 )]
464 #[document_returns("A new identity containing the result of applying the function.")]
466 #[document_examples]
467 fn apply<'a, FnBrand: 'a + CloneFn, A: 'a + Clone, B: 'a>(
481 ff: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, <FnBrand as CloneFn>::Of<'a, A, B>>),
482 fa: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
483 ) -> Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>) {
484 fa.apply(ff.map(|f| move |a| f(a)))
485 }
486 }
487
488 impl Semimonad for IdentityBrand {
489 #[document_signature]
493 #[document_type_parameters(
495 "The lifetime of the values.",
496 "The type of the result of the first computation.",
497 "The type of the result of the second computation."
498 )]
499 #[document_parameters(
501 "The first identity.",
502 "The function to apply to the value inside the identity."
503 )]
504 #[document_returns("The result of applying `f` to the value.")]
506 #[document_examples]
507 fn bind<'a, A: 'a, B: 'a>(
520 ma: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
521 func: impl Fn(A) -> Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>) + 'a,
522 ) -> Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>) {
523 ma.bind(func)
524 }
525 }
526
527 impl Foldable for IdentityBrand {
528 #[document_signature]
532 #[document_type_parameters(
534 "The lifetime of the values.",
535 "The brand of the cloneable function to use.",
536 "The type of the elements in the structure.",
537 "The type of the accumulator."
538 )]
539 #[document_parameters(
541 "The function to apply to each element and the accumulator.",
542 "The initial value of the accumulator.",
543 "The identity to fold."
544 )]
545 #[document_returns("The final accumulator value.")]
547 #[document_examples]
548 fn fold_right<'a, FnBrand, A: 'a, B: 'a>(
561 func: impl Fn(A, B) -> B + 'a,
562 initial: B,
563 fa: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
564 ) -> B
565 where
566 FnBrand: CloneFn + 'a, {
567 fa.fold_right(func, initial)
568 }
569
570 #[document_signature]
574 #[document_type_parameters(
576 "The lifetime of the values.",
577 "The brand of the cloneable function to use.",
578 "The type of the elements in the structure.",
579 "The type of the accumulator."
580 )]
581 #[document_parameters(
583 "The function to apply to the accumulator and each element.",
584 "The initial value of the accumulator.",
585 "The structure to fold."
586 )]
587 #[document_returns("The final accumulator value.")]
589 #[document_examples]
590 fn fold_left<'a, FnBrand, A: 'a, B: 'a>(
603 func: impl Fn(B, A) -> B + 'a,
604 initial: B,
605 fa: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
606 ) -> B
607 where
608 FnBrand: CloneFn + 'a, {
609 fa.fold_left(func, initial)
610 }
611
612 #[document_signature]
616 #[document_type_parameters(
618 "The lifetime of the values.",
619 "The brand of the cloneable function to use.",
620 "The type of the elements in the structure.",
621 "The type of the monoid."
622 )]
623 #[document_parameters("The mapping function.", "The identity to fold.")]
625 #[document_returns("The monoid value.")]
627 #[document_examples]
629 fn fold_map<'a, FnBrand, A: 'a, M>(
642 func: impl Fn(A) -> M + 'a,
643 fa: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
644 ) -> M
645 where
646 M: Monoid + 'a,
647 FnBrand: CloneFn + 'a, {
648 fa.fold_map(func)
649 }
650 }
651
652 impl Traversable for IdentityBrand {
653 #[document_signature]
657 #[document_type_parameters(
659 "The lifetime of the values.",
660 "The type of the elements in the traversable structure.",
661 "The type of the elements in the resulting traversable structure.",
662 "The applicative context."
663 )]
664 #[document_parameters(
666 "The function to apply to each element, returning a value in an applicative context.",
667 "The identity to traverse."
668 )]
669 #[document_returns("The identity wrapped in the applicative context.")]
671 #[document_examples]
672 fn traverse<'a, A: 'a + Clone, B: 'a + Clone, F: Applicative>(
686 func: impl Fn(A) -> Apply!(<F as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>) + 'a,
687 ta: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
688 ) -> 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>)>)
689 where
690 Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>): Clone, {
691 ta.traverse::<B, F>(func)
692 }
693
694 #[document_signature]
698 #[document_type_parameters(
700 "The lifetime of the values.",
701 "The type of the elements in the traversable structure.",
702 "The applicative context."
703 )]
704 #[document_parameters("The identity containing the applicative value.")]
706 #[document_returns("The result of the traversal.")]
708 #[document_examples]
713 fn sequence<'a, A: 'a + Clone, F: Applicative>(
726 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>)>)
727 ) -> 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>)>)
728 where
729 Apply!(<F as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>): Clone,
730 Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>): Clone, {
731 ta.traverse::<A, F>(|a| a)
732 }
733 }
734
735 impl MonadRec for IdentityBrand {
736 #[document_signature]
741 #[document_type_parameters(
743 "The lifetime of the computation.",
744 "The type of the initial value and loop state.",
745 "The type of the result."
746 )]
747 #[document_parameters("The step function.", "The initial value.")]
749 #[document_returns("An identity containing the result of the computation.")]
751 #[document_examples]
753 fn tail_rec_m<'a, A: 'a, B: 'a>(
777 func: impl Fn(
778 A,
779 )
780 -> Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, ControlFlow<B, A>>)
781 + 'a,
782 initial: A,
783 ) -> Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>) {
784 let mut current = initial;
785 loop {
786 match func(current).0 {
787 ControlFlow::Continue(next) => current = next,
788 ControlFlow::Break(b) => return Identity(b),
789 }
790 }
791 }
792 }
793
794 impl Extract for IdentityBrand {
795 #[document_signature]
800 #[document_type_parameters(
802 "The lifetime of the value.",
803 "The type of the value inside the identity."
804 )]
805 #[document_parameters("The identity to extract from.")]
807 #[document_returns("The inner value.")]
809 #[document_examples]
811 fn extract<'a, A: 'a>(
823 fa: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>)
824 ) -> A {
825 fa.0
826 }
827 }
828
829 impl Extend for IdentityBrand {
830 #[document_signature]
836 #[document_type_parameters(
838 "The lifetime of the values.",
839 "The type of the value inside the identity.",
840 "The result type of the extension function."
841 )]
842 #[document_parameters(
844 "The function that consumes an `Identity` and produces a value.",
845 "The identity to extend over."
846 )]
847 #[document_returns("A new identity containing the result of applying the function.")]
849 #[document_examples]
851 fn extend<'a, A: 'a + Clone, B: 'a>(
864 f: impl Fn(Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>)) -> B + 'a,
865 wa: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
866 ) -> Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>) {
867 Identity(f(wa))
868 }
869 }
870 impl RefFunctor for IdentityBrand {
873 #[document_signature]
875 #[document_type_parameters(
877 "The lifetime of the value.",
878 "The type of the wrapped value.",
879 "The type of the resulting value."
880 )]
881 #[document_parameters(
883 "The function to apply to the value reference.",
884 "The identity to map over."
885 )]
886 #[document_returns("A new identity containing the result.")]
888 #[document_examples]
890 fn ref_map<'a, A: 'a, B: 'a>(
904 func: impl Fn(&A) -> B + 'a,
905 fa: &Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
906 ) -> Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>) {
907 Identity(func(&fa.0))
908 }
909 }
910
911 impl RefFoldable for IdentityBrand {
912 #[document_signature]
914 #[document_type_parameters(
916 "The lifetime of the value.",
917 "The brand of the cloneable function wrapper.",
918 "The type of the wrapped value.",
919 "The monoid type."
920 )]
921 #[document_parameters(
923 "The function to map the value reference to a monoid.",
924 "The identity to fold."
925 )]
926 #[document_returns("The monoid value.")]
928 #[document_examples]
930 fn ref_fold_map<'a, FnBrand, A: 'a + Clone, M>(
945 func: impl Fn(&A) -> M + 'a,
946 fa: &Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
947 ) -> M
948 where
949 FnBrand: LiftFn + 'a,
950 M: Monoid + 'a, {
951 func(&fa.0)
952 }
953 }
954
955 impl RefTraversable for IdentityBrand {
956 #[document_signature]
958 #[document_type_parameters(
960 "The lifetime of the value.",
961 "The brand of the cloneable function wrapper.",
962 "The type of the wrapped value.",
963 "The type of the resulting value.",
964 "The applicative functor brand."
965 )]
966 #[document_parameters(
968 "The function to apply to the value reference.",
969 "The identity to traverse."
970 )]
971 #[document_returns("The result in the applicative context.")]
973 #[document_examples]
975 fn ref_traverse<'a, FnBrand, A: 'a + Clone, B: 'a + Clone, F: Applicative>(
991 func: impl Fn(&A) -> Apply!(<F as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>) + 'a,
992 ta: &Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
993 ) -> 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>)>)
994 where
995 FnBrand: LiftFn + 'a,
996 Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>): Clone,
997 Apply!(<F as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>): Clone, {
998 F::map(Identity, func(&ta.0))
999 }
1000 }
1001
1002 impl WithIndex for IdentityBrand {
1005 type Index = ();
1006 }
1007
1008 impl FunctorWithIndex for IdentityBrand {
1009 #[document_signature]
1011 #[document_type_parameters("The lifetime.", "The input type.", "The output type.")]
1012 #[document_parameters("The function to apply with index.", "The Identity value.")]
1013 #[document_returns("The transformed Identity value.")]
1014 #[document_examples]
1015 fn map_with_index<'a, A: 'a, B: 'a>(
1027 func: impl Fn((), A) -> B + 'a,
1028 fa: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
1029 ) -> Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>) {
1030 Identity(func((), fa.0))
1031 }
1032 }
1033
1034 impl FoldableWithIndex for IdentityBrand {
1035 #[document_signature]
1037 #[document_type_parameters(
1038 "The lifetime.",
1039 "The brand of the cloneable function to use.",
1040 "The element type.",
1041 "The monoid type."
1042 )]
1043 #[document_parameters("The function to apply with index.", "The Identity value.")]
1044 #[document_returns("The monoid result.")]
1045 #[document_examples]
1046 fn fold_map_with_index<'a, FnBrand, A: 'a + Clone, R: Monoid + 'a>(
1061 func: impl Fn((), A) -> R + 'a,
1062 fa: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
1063 ) -> R
1064 where
1065 FnBrand: LiftFn + 'a, {
1066 func((), fa.0)
1067 }
1068 }
1069
1070 impl TraversableWithIndex for IdentityBrand {
1071 #[document_signature]
1073 #[document_type_parameters(
1074 "The lifetime.",
1075 "The element type.",
1076 "The output type.",
1077 "The applicative brand."
1078 )]
1079 #[document_parameters("The function to apply with index.", "The Identity value.")]
1080 #[document_returns("The result in the applicative context.")]
1081 #[document_examples]
1082 fn traverse_with_index<'a, A: 'a, B: 'a + Clone, M: Applicative>(
1098 func: impl Fn((), A) -> Apply!(<M as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>) + 'a,
1099 ta: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
1100 ) -> Apply!(<M as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>)>)
1101 where
1102 Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>): Clone,
1103 Apply!(<M as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>): Clone, {
1104 M::map::<B, Identity<B>>(Identity, func((), ta.0))
1105 }
1106 }
1107
1108 impl RefFunctorWithIndex for IdentityBrand {
1111 #[document_signature]
1113 #[document_type_parameters("The lifetime.", "The input type.", "The output type.")]
1114 #[document_parameters("The function to apply with index.", "The Identity value.")]
1115 #[document_returns("The transformed Identity value.")]
1116 #[document_examples]
1117 fn ref_map_with_index<'a, A: 'a, B: 'a>(
1130 func: impl Fn((), &A) -> B + 'a,
1131 fa: &Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
1132 ) -> Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>) {
1133 Identity(func((), &fa.0))
1134 }
1135 }
1136
1137 impl RefFoldableWithIndex for IdentityBrand {
1138 #[document_signature]
1140 #[document_type_parameters(
1141 "The lifetime.",
1142 "The brand of the cloneable function.",
1143 "The element type.",
1144 "The monoid type."
1145 )]
1146 #[document_parameters("The function to apply with index.", "The Identity value.")]
1147 #[document_returns("The monoid result.")]
1148 #[document_examples]
1149 fn ref_fold_map_with_index<'a, FnBrand, A: 'a + Clone, R: Monoid + 'a>(
1164 func: impl Fn((), &A) -> R + 'a,
1165 fa: &Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
1166 ) -> R
1167 where
1168 FnBrand: LiftFn + 'a, {
1169 func((), &fa.0)
1170 }
1171 }
1172
1173 impl RefTraversableWithIndex for IdentityBrand {
1174 #[document_signature]
1176 #[document_type_parameters(
1177 "The lifetime.",
1178 "The element type.",
1179 "The output type.",
1180 "The applicative brand."
1181 )]
1182 #[document_parameters("The function to apply with index.", "The Identity value.")]
1183 #[document_returns("The result in the applicative context.")]
1184 #[document_examples]
1185 fn ref_traverse_with_index<'a, A: 'a + Clone, B: 'a + Clone, M: Applicative>(
1201 f: impl Fn((), &A) -> Apply!(<M as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>) + 'a,
1202 ta: &Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
1203 ) -> Apply!(<M as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>)>)
1204 where
1205 Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>): Clone,
1206 Apply!(<M as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>): Clone, {
1207 M::map(Identity, f((), &ta.0))
1208 }
1209 }
1210
1211 impl RefPointed for IdentityBrand {
1214 #[document_signature]
1216 #[document_type_parameters("The lifetime.", "The value type.")]
1217 #[document_parameters("The reference to wrap.")]
1218 #[document_returns("An Identity containing a clone of the value.")]
1219 #[document_examples]
1220 fn ref_pure<'a, A: Clone + 'a>(
1233 a: &A
1234 ) -> Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>) {
1235 Identity(a.clone())
1236 }
1237 }
1238
1239 impl RefLift for IdentityBrand {
1240 #[document_signature]
1242 #[document_type_parameters("The lifetime.", "First input.", "Second input.", "Output.")]
1243 #[document_parameters(
1244 "The binary function.",
1245 "The first Identity.",
1246 "The second Identity."
1247 )]
1248 #[document_returns("The combined Identity.")]
1249 #[document_examples]
1250 fn ref_lift2<'a, A: 'a, B: 'a, C: 'a>(
1266 func: impl Fn(&A, &B) -> C + 'a,
1267 fa: &Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
1268 fb: &Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>),
1269 ) -> Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, C>) {
1270 Identity(func(&fa.0, &fb.0))
1271 }
1272 }
1273
1274 impl RefSemiapplicative for IdentityBrand {
1275 #[document_signature]
1277 #[document_type_parameters(
1278 "The lifetime.",
1279 "The function brand.",
1280 "The input type.",
1281 "The output type."
1282 )]
1283 #[document_parameters(
1284 "The Identity containing the function.",
1285 "The Identity containing the value."
1286 )]
1287 #[document_returns("The Identity containing the result.")]
1288 #[document_examples]
1289 fn ref_apply<'a, FnBrand: 'a + CloneFn<Ref>, A: 'a, B: 'a>(
1303 ff: &Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, <FnBrand as CloneFn<Ref>>::Of<'a, A, B>>),
1304 fa: &Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
1305 ) -> Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>) {
1306 Identity((*ff.0)(&fa.0))
1307 }
1308 }
1309
1310 impl RefSemimonad for IdentityBrand {
1311 #[document_signature]
1313 #[document_type_parameters("The lifetime.", "The input type.", "The output type.")]
1314 #[document_parameters("The input Identity.", "The function to apply by reference.")]
1315 #[document_returns("The resulting Identity.")]
1316 #[document_examples]
1317 fn ref_bind<'a, A: 'a, B: 'a>(
1332 fa: &Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
1333 f: impl Fn(&A) -> Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>) + 'a,
1334 ) -> Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>) {
1335 f(&fa.0)
1336 }
1337 }
1338}
1339pub use inner::*;
1340
1341#[cfg(test)]
1342mod tests {
1343 use {
1344 super::inner::Identity,
1345 crate::{
1346 brands::{
1347 IdentityBrand,
1348 OptionBrand,
1349 RcFnBrand,
1350 },
1351 classes::*,
1352 functions::*,
1353 },
1354 quickcheck_macros::quickcheck,
1355 };
1356
1357 #[quickcheck]
1361 fn functor_identity(x: i32) -> bool {
1362 let x = Identity(x);
1363 explicit::map::<IdentityBrand, _, _, _, _>(identity, x) == x
1364 }
1365
1366 #[quickcheck]
1368 fn functor_composition(x: i32) -> bool {
1369 let x = Identity(x);
1370 let f = |x: i32| x.wrapping_add(1);
1371 let g = |x: i32| x.wrapping_mul(2);
1372 explicit::map::<IdentityBrand, _, _, _, _>(compose(f, g), x)
1373 == explicit::map::<IdentityBrand, _, _, _, _>(
1374 f,
1375 explicit::map::<IdentityBrand, _, _, _, _>(g, x),
1376 )
1377 }
1378
1379 #[quickcheck]
1383 fn applicative_identity(v: i32) -> bool {
1384 let v = Identity(v);
1385 apply::<RcFnBrand, IdentityBrand, _, _>(
1386 pure::<IdentityBrand, _>(<RcFnBrand as LiftFn>::new(identity)),
1387 v,
1388 ) == v
1389 }
1390
1391 #[quickcheck]
1393 fn applicative_homomorphism(x: i32) -> bool {
1394 let f = |x: i32| x.wrapping_mul(2);
1395 apply::<RcFnBrand, IdentityBrand, _, _>(
1396 pure::<IdentityBrand, _>(<RcFnBrand as LiftFn>::new(f)),
1397 pure::<IdentityBrand, _>(x),
1398 ) == pure::<IdentityBrand, _>(f(x))
1399 }
1400
1401 #[quickcheck]
1403 fn applicative_composition(
1404 w: i32,
1405 u_val: i32,
1406 v_val: i32,
1407 ) -> bool {
1408 let w = Identity(w);
1409 let v_fn = move |x: i32| x.wrapping_mul(v_val);
1410 let u_fn = move |x: i32| x.wrapping_add(u_val);
1411
1412 let v = pure::<IdentityBrand, _>(<RcFnBrand as LiftFn>::new(v_fn));
1413 let u = pure::<IdentityBrand, _>(<RcFnBrand as LiftFn>::new(u_fn));
1414
1415 let vw = apply::<RcFnBrand, IdentityBrand, _, _>(v.clone(), w);
1417 let rhs = apply::<RcFnBrand, IdentityBrand, _, _>(u.clone(), vw);
1418
1419 let composed = move |x| u_fn(v_fn(x));
1422 let uv = pure::<IdentityBrand, _>(<RcFnBrand as LiftFn>::new(composed));
1423
1424 let lhs = apply::<RcFnBrand, IdentityBrand, _, _>(uv, w);
1425
1426 lhs == rhs
1427 }
1428
1429 #[quickcheck]
1431 fn applicative_interchange(y: i32) -> bool {
1432 let f = |x: i32| x.wrapping_mul(2);
1434 let u = pure::<IdentityBrand, _>(<RcFnBrand as LiftFn>::new(f));
1435
1436 let lhs = apply::<RcFnBrand, IdentityBrand, _, _>(u.clone(), pure::<IdentityBrand, _>(y));
1437
1438 let rhs_fn = <RcFnBrand as LiftFn>::new(move |f: std::rc::Rc<dyn Fn(i32) -> i32>| f(y));
1439 let rhs = apply::<RcFnBrand, IdentityBrand, _, _>(pure::<IdentityBrand, _>(rhs_fn), u);
1440
1441 lhs == rhs
1442 }
1443
1444 #[quickcheck]
1448 fn monad_left_identity(a: i32) -> bool {
1449 let f = |x: i32| Identity(x.wrapping_mul(2));
1450 explicit::bind::<IdentityBrand, _, _, _, _>(pure::<IdentityBrand, _>(a), f) == f(a)
1451 }
1452
1453 #[quickcheck]
1455 fn monad_right_identity(m: i32) -> bool {
1456 let m = Identity(m);
1457 explicit::bind::<IdentityBrand, _, _, _, _>(m, pure::<IdentityBrand, _>) == m
1458 }
1459
1460 #[quickcheck]
1462 fn monad_associativity(m: i32) -> bool {
1463 let m = Identity(m);
1464 let f = |x: i32| Identity(x.wrapping_mul(2));
1465 let g = |x: i32| Identity(x.wrapping_add(1));
1466 explicit::bind::<IdentityBrand, _, _, _, _>(
1467 explicit::bind::<IdentityBrand, _, _, _, _>(m, f),
1468 g,
1469 ) == explicit::bind::<IdentityBrand, _, _, _, _>(m, |x| {
1470 explicit::bind::<IdentityBrand, _, _, _, _>(f(x), g)
1471 })
1472 }
1473
1474 #[test]
1478 fn map_test() {
1479 assert_eq!(
1480 explicit::map::<IdentityBrand, _, _, _, _>(|x: i32| x + 1, Identity(1)),
1481 Identity(2)
1482 );
1483 }
1484
1485 #[test]
1487 fn bind_test() {
1488 assert_eq!(
1489 explicit::bind::<IdentityBrand, _, _, _, _>(Identity(1), |x| Identity(x + 1)),
1490 Identity(2)
1491 );
1492 }
1493
1494 #[test]
1496 fn fold_right_test() {
1497 assert_eq!(
1498 crate::functions::explicit::fold_right::<RcFnBrand, IdentityBrand, _, _, _, _>(
1499 |x: i32, acc| x + acc,
1500 0,
1501 Identity(1)
1502 ),
1503 1
1504 );
1505 }
1506
1507 #[test]
1509 fn fold_left_test() {
1510 assert_eq!(
1511 crate::functions::explicit::fold_left::<RcFnBrand, IdentityBrand, _, _, _, _>(
1512 |acc, x: i32| acc + x,
1513 0,
1514 Identity(1)
1515 ),
1516 1
1517 );
1518 }
1519
1520 #[test]
1522 fn traverse_test() {
1523 assert_eq!(
1524 crate::classes::traversable::traverse::<IdentityBrand, _, _, OptionBrand>(
1525 |x: i32| Some(x + 1),
1526 Identity(1)
1527 ),
1528 Some(Identity(2))
1529 );
1530 }
1531
1532 #[quickcheck]
1536 fn monad_rec_identity(x: i32) -> bool {
1537 use {
1538 crate::classes::monad_rec::tail_rec_m,
1539 core::ops::ControlFlow,
1540 };
1541 tail_rec_m::<IdentityBrand, _, _>(|a| Identity(ControlFlow::Break(a)), x) == Identity(x)
1542 }
1543
1544 #[test]
1546 fn monad_rec_sum_range() {
1547 use {
1548 crate::classes::monad_rec::tail_rec_m,
1549 core::ops::ControlFlow,
1550 };
1551 let result = tail_rec_m::<IdentityBrand, _, _>(
1552 |(n, acc)| {
1553 if n == 0 {
1554 Identity(ControlFlow::Break(acc))
1555 } else {
1556 Identity(ControlFlow::Continue((n - 1, acc + n)))
1557 }
1558 },
1559 (100i64, 0i64),
1560 );
1561 assert_eq!(result, Identity(5050));
1562 }
1563
1564 #[test]
1566 fn monad_rec_stack_safety() {
1567 use {
1568 crate::classes::monad_rec::tail_rec_m,
1569 core::ops::ControlFlow,
1570 };
1571 let iterations: i64 = 200_000;
1572 let result = tail_rec_m::<IdentityBrand, _, _>(
1573 |acc| {
1574 if acc < iterations {
1575 Identity(ControlFlow::Continue(acc + 1))
1576 } else {
1577 Identity(ControlFlow::Break(acc))
1578 }
1579 },
1580 0i64,
1581 );
1582 assert_eq!(result, Identity(iterations));
1583 }
1584
1585 #[quickcheck]
1589 fn extract_pure(x: i32) -> bool {
1590 use crate::classes::extract::extract;
1591 extract::<IdentityBrand, _>(pure::<IdentityBrand, _>(x)) == x
1592 }
1593
1594 #[quickcheck]
1596 fn comonad_left_identity(x: i32) -> bool {
1597 use crate::classes::{
1598 extend::extend,
1599 extract::extract,
1600 };
1601 let f = |w: Identity<i32>| w.0.wrapping_mul(3);
1602 let wa = Identity(x);
1603 extract::<IdentityBrand, _>(extend::<IdentityBrand, _, _>(f, wa)) == f(wa)
1604 }
1605
1606 #[quickcheck]
1608 fn comonad_right_identity(x: i32) -> bool {
1609 use crate::classes::{
1610 extend::extend,
1611 extract::extract,
1612 };
1613 extend::<IdentityBrand, _, _>(extract::<IdentityBrand, _>, Identity(x)) == Identity(x)
1614 }
1615
1616 #[quickcheck]
1618 fn extend_associativity(x: i32) -> bool {
1619 use crate::classes::extend::extend;
1620 let g = |w: Identity<i32>| w.0.wrapping_mul(2);
1621 let f = |w: Identity<i32>| w.0.wrapping_add(1);
1622 let wa = Identity(x);
1623 let lhs = extend::<IdentityBrand, _, _>(f, extend::<IdentityBrand, _, _>(g, wa));
1624 let rhs = extend::<IdentityBrand, _, _>(
1625 |w: Identity<i32>| f(extend::<IdentityBrand, _, _>(g, w)),
1626 wa,
1627 );
1628 lhs == rhs
1629 }
1630
1631 #[quickcheck]
1633 fn comonad_map_extract(x: i32) -> bool {
1634 use crate::classes::extract::extract;
1635 let f = |a: i32| a.wrapping_mul(5);
1636 let wa = Identity(x);
1637 extract::<IdentityBrand, _>(explicit::map::<IdentityBrand, _, _, _, _>(f, wa))
1638 == f(extract::<IdentityBrand, _>(wa))
1639 }
1640
1641 #[test]
1643 fn extract_test() {
1644 use crate::classes::extract::extract;
1645 assert_eq!(extract::<IdentityBrand, _>(Identity(42)), 42);
1646 }
1647
1648 #[test]
1650 fn extend_test() {
1651 use crate::classes::extend::extend;
1652 let result = extend::<IdentityBrand, _, _>(|w: Identity<i32>| w.0 * 2, Identity(21));
1653 assert_eq!(result, Identity(42));
1654 }
1655
1656 #[quickcheck]
1660 fn ref_functor_identity(v: i32) -> bool {
1661 use crate::classes::ref_functor::RefFunctor;
1662 IdentityBrand::ref_map(|x: &i32| *x, &Identity(v)) == Identity(v)
1663 }
1664
1665 #[quickcheck]
1667 fn ref_functor_composition(v: i32) -> bool {
1668 use crate::classes::ref_functor::RefFunctor;
1669 let f = |x: &i32| x.wrapping_add(1);
1670 let g = |x: &i32| x.wrapping_mul(2);
1671 IdentityBrand::ref_map(|x: &i32| f(&g(x)), &Identity(v))
1672 == IdentityBrand::ref_map(f, &IdentityBrand::ref_map(g, &Identity(v)))
1673 }
1674
1675 #[quickcheck]
1679 fn ref_semimonad_left_identity(x: i32) -> bool {
1680 use crate::classes::ref_semimonad::RefSemimonad;
1681 IdentityBrand::ref_bind(&Identity(x), |a: &i32| Identity(*a)) == Identity(x)
1682 }
1683}