1#[fp_macros::document_module]
6mod inner {
7 use {
8 crate::{
9 Apply,
10 brands::OptionBrand,
11 classes::{
12 Alt,
13 Applicative,
14 ApplyFirst,
15 ApplySecond,
16 CloneableFn,
17 Compactable,
18 Filterable,
19 Foldable,
20 Functor,
21 Lift,
22 Monoid,
23 ParFoldable,
24 Plus,
25 Pointed,
26 Semiapplicative,
27 Semimonad,
28 SendCloneableFn,
29 Traversable,
30 Witherable,
31 foldable_with_index::FoldableWithIndex,
32 functor_with_index::FunctorWithIndex,
33 traversable_with_index::TraversableWithIndex,
34 },
35 impl_kind,
36 kinds::*,
37 },
38 fp_macros::*,
39 };
40
41 impl_kind! {
42 for OptionBrand {
43 type Of<'a, A: 'a>: 'a = Option<A>;
44 }
45 }
46
47 impl Functor for OptionBrand {
48 #[document_signature]
52 #[document_type_parameters(
54 "The lifetime of the value.",
55 "The type of the value inside the option.",
56 "The type of the result of applying the function."
57 )]
58 #[document_parameters("The function to apply to the value.", "The option to map over.")]
60 #[document_returns(
62 "A new option containing the result of applying the function, or `None`."
63 )]
64 #[document_examples]
66 fn map<'a, A: 'a, B: 'a>(
78 func: impl Fn(A) -> B + 'a,
79 fa: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
80 ) -> Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>) {
81 fa.map(func)
82 }
83 }
84
85 impl Lift for OptionBrand {
86 #[document_signature]
90 #[document_type_parameters(
92 "The lifetime of the values.",
93 "The type of the first option's value.",
94 "The type of the second option's value.",
95 "The return type of the function."
96 )]
97 #[document_parameters(
99 "The binary function to apply.",
100 "The first option.",
101 "The second option."
102 )]
103 #[document_returns("`Some(f(a, b))` if both options are `Some`, otherwise `None`.")]
105 #[document_examples]
106 fn lift2<'a, A, B, C>(
119 func: impl Fn(A, B) -> C + 'a,
120 fa: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
121 fb: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>),
122 ) -> Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, C>)
123 where
124 A: 'a,
125 B: 'a,
126 C: 'a, {
127 fa.zip(fb).map(|(a, b)| func(a, b))
128 }
129 }
130
131 impl Pointed for OptionBrand {
132 #[document_signature]
136 #[document_type_parameters("The lifetime of the value.", "The type of the value to wrap.")]
138 #[document_parameters("The value to wrap.")]
140 #[document_returns("`Some(a)`.")]
142 #[document_examples]
144 fn pure<'a, A: 'a>(a: A) -> Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>) {
155 Some(a)
156 }
157 }
158
159 impl ApplyFirst for OptionBrand {}
160 impl ApplySecond for OptionBrand {}
161
162 impl Semiapplicative for OptionBrand {
163 #[document_signature]
167 #[document_type_parameters(
169 "The lifetime of the values.",
170 "The brand of the cloneable function wrapper.",
171 "The type of the input value.",
172 "The type of the output value."
173 )]
174 #[document_parameters(
176 "The option containing the function.",
177 "The option containing the value."
178 )]
179 #[document_returns("`Some(f(a))` if both are `Some`, otherwise `None`.")]
181 #[document_examples]
182 fn apply<'a, FnBrand: 'a + CloneableFn, A: 'a + Clone, B: 'a>(
196 ff: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, <FnBrand as CloneableFn>::Of<'a, A, B>>),
197 fa: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
198 ) -> Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>) {
199 match (ff, fa) {
200 (Some(f), Some(a)) => Some(f(a)),
201 _ => None,
202 }
203 }
204 }
205
206 impl Semimonad for OptionBrand {
207 #[document_signature]
211 #[document_type_parameters(
213 "The lifetime of the values.",
214 "The type of the result of the first computation.",
215 "The type of the result of the second computation."
216 )]
217 #[document_parameters(
219 "The first option.",
220 "The function to apply to the value inside the option."
221 )]
222 #[document_returns(
224 "The result of applying `f` to the value if `ma` is `Some`, otherwise `None`."
225 )]
226 #[document_examples]
227 fn bind<'a, A: 'a, B: 'a>(
239 ma: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
240 func: impl Fn(A) -> Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>) + 'a,
241 ) -> Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>) {
242 ma.and_then(func)
243 }
244 }
245
246 impl Alt for OptionBrand {
247 #[document_signature]
251 #[document_type_parameters("The lifetime of the values.", "The type of the value.")]
253 #[document_parameters("The first option.", "The second option.")]
255 #[document_returns("The first `Some` value, or `None`.")]
257 #[document_examples]
258 fn alt<'a, A: 'a>(
271 fa1: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
272 fa2: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
273 ) -> Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>) {
274 fa1.or(fa2)
275 }
276 }
277
278 impl Plus for OptionBrand {
279 #[document_signature]
281 #[document_type_parameters("The lifetime of the value.", "The type of the value.")]
283 #[document_returns("`None`.")]
285 #[document_examples]
286 fn empty<'a, A: 'a>() -> Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>) {
297 None
298 }
299 }
300
301 impl Foldable for OptionBrand {
302 #[document_signature]
306 #[document_type_parameters(
308 "The lifetime of the values.",
309 "The brand of the cloneable function to use.",
310 "The type of the elements in the structure.",
311 "The type of the accumulator."
312 )]
313 #[document_parameters("The folding function.", "The initial value.", "The option to fold.")]
315 #[document_returns("`func(a, initial)` if `fa` is `Some(a)`, otherwise `initial`.")]
317 #[document_examples]
319 fn fold_right<'a, FnBrand, A: 'a + Clone, B: 'a>(
331 func: impl Fn(A, B) -> B + 'a,
332 initial: B,
333 fa: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
334 ) -> B
335 where
336 FnBrand: CloneableFn + 'a, {
337 match fa {
338 Some(a) => func(a, initial),
339 None => initial,
340 }
341 }
342
343 #[document_signature]
347 #[document_type_parameters(
349 "The lifetime of the values.",
350 "The brand of the cloneable function to use.",
351 "The type of the elements in the structure.",
352 "The type of the accumulator."
353 )]
354 #[document_parameters(
356 "The function to apply to the accumulator and each element.",
357 "The initial value of the accumulator.",
358 "The option to fold."
359 )]
360 #[document_returns("`f(initial, a)` if `fa` is `Some(a)`, otherwise `initial`.")]
362 #[document_examples]
363 fn fold_left<'a, FnBrand, A: 'a + Clone, B: 'a>(
375 func: impl Fn(B, A) -> B + 'a,
376 initial: B,
377 fa: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
378 ) -> B
379 where
380 FnBrand: CloneableFn + 'a, {
381 match fa {
382 Some(a) => func(initial, a),
383 None => initial,
384 }
385 }
386
387 #[document_signature]
391 #[document_type_parameters(
393 "The lifetime of the values.",
394 "The brand of the cloneable function to use.",
395 "The type of the elements in the structure.",
396 "The type of the monoid."
397 )]
398 #[document_parameters("The mapping function.", "The option to fold.")]
400 #[document_returns("`func(a)` if `fa` is `Some(a)`, otherwise `M::empty()`.")]
402 #[document_examples]
404 fn fold_map<'a, FnBrand, A: 'a + Clone, M>(
416 func: impl Fn(A) -> M + 'a,
417 fa: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
418 ) -> M
419 where
420 M: Monoid + 'a,
421 FnBrand: CloneableFn + 'a, {
422 match fa {
423 Some(a) => func(a),
424 None => M::empty(),
425 }
426 }
427 }
428
429 impl Traversable for OptionBrand {
430 #[document_signature]
434 #[document_type_parameters(
436 "The lifetime of the values.",
437 "The type of the elements in the traversable structure.",
438 "The type of the elements in the resulting traversable structure.",
439 "The applicative context."
440 )]
441 #[document_parameters(
443 "The function to apply to each element, returning a value in an applicative context.",
444 "The option to traverse."
445 )]
446 #[document_returns("The option wrapped in the applicative context.")]
448 #[document_examples]
449 fn traverse<'a, A: 'a + Clone, B: 'a + Clone, F: Applicative>(
461 func: impl Fn(A) -> Apply!(<F as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>) + 'a,
462 ta: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
463 ) -> 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>)>)
464 where
465 Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>): Clone, {
466 match ta {
467 Some(a) => F::map(|b| Some(b), func(a)),
468 None => F::pure(None),
469 }
470 }
471
472 #[document_signature]
476 #[document_type_parameters(
478 "The lifetime of the values.",
479 "The type of the elements in the traversable structure.",
480 "The applicative context."
481 )]
482 #[document_parameters("The option containing the applicative value.")]
484 #[document_returns("The result of the traversal.")]
486 #[document_examples]
491 fn sequence<'a, A: 'a + Clone, F: Applicative>(
503 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>)>)
504 ) -> 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>)>)
505 where
506 Apply!(<F as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>): Clone,
507 Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>): Clone, {
508 match ta {
509 Some(fa) => F::map(|a| Some(a), fa),
510 None => F::pure(None),
511 }
512 }
513 }
514
515 impl FunctorWithIndex<()> for OptionBrand {
516 #[document_signature]
518 #[document_type_parameters(
519 "The lifetime of the value.",
520 "The type of the value inside the option.",
521 "The type of the result of applying the function."
522 )]
523 #[document_parameters(
524 "The function to apply to the value and its index.",
525 "The option to map over."
526 )]
527 #[document_returns(
528 "A new option containing the result of applying the function, or `None`."
529 )]
530 #[document_examples]
531 fn map_with_index<'a, A: 'a, B: 'a>(
543 f: impl Fn((), A) -> B + 'a,
544 fa: Option<A>,
545 ) -> Option<B> {
546 fa.map(|a| f((), a))
547 }
548 }
549
550 impl FoldableWithIndex<()> for OptionBrand {
551 #[document_signature]
553 #[document_type_parameters(
554 "The lifetime of the value.",
555 "The type of the value inside the option.",
556 "The monoid type."
557 )]
558 #[document_parameters(
559 "The function to apply to the value and its index.",
560 "The option to fold."
561 )]
562 #[document_returns("The monoid value.")]
563 #[document_examples]
564 fn fold_map_with_index<'a, A: 'a, R: Monoid>(
577 f: impl Fn((), A) -> R + 'a,
578 fa: Option<A>,
579 ) -> R {
580 match fa {
581 Some(a) => f((), a),
582 None => R::empty(),
583 }
584 }
585 }
586
587 impl TraversableWithIndex<()> for OptionBrand {
588 #[document_signature]
590 #[document_type_parameters(
591 "The lifetime of the value.",
592 "The type of the value inside the option.",
593 "The type of the result.",
594 "The applicative context."
595 )]
596 #[document_parameters(
597 "The function to apply to the value and its index, returning a value in an applicative context.",
598 "The option to traverse."
599 )]
600 #[document_returns("The option wrapped in the applicative context.")]
601 #[document_examples]
602 fn traverse_with_index<'a, A: 'a, B: 'a + Clone, M: Applicative>(
617 f: impl Fn((), A) -> M::Of<'a, B> + 'a,
618 ta: Option<A>,
619 ) -> M::Of<'a, Option<B>> {
620 match ta {
621 Some(a) => M::map(|b| Some(b), f((), a)),
622 None => M::pure(None),
623 }
624 }
625 }
626
627 impl ParFoldable for OptionBrand {
628 #[document_signature]
632 #[document_type_parameters(
634 "The lifetime of the values.",
635 "The brand of the cloneable function wrapper.",
636 "The element type.",
637 "The monoid type."
638 )]
639 #[document_parameters("The mapping function.", "The option to fold.")]
641 #[document_returns("The combined monoid value.")]
643 #[document_examples]
645 fn par_fold_map<'a, FnBrand, A, M>(
658 func: <FnBrand as SendCloneableFn>::SendOf<'a, A, M>,
659 fa: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
660 ) -> M
661 where
662 FnBrand: 'a + SendCloneableFn,
663 A: 'a + Clone + Send + Sync,
664 M: Monoid + Send + Sync + 'a, {
665 match fa {
666 Some(a) => func(a),
667 None => M::empty(),
668 }
669 }
670 }
671
672 impl Compactable for OptionBrand {
673 #[document_signature]
677 #[document_type_parameters("The lifetime of the values.", "The type of the elements.")]
679 #[document_parameters("The nested option.")]
681 #[document_returns("The flattened option.")]
683 #[document_examples]
685 fn compact<'a, A: 'a>(
697 fa: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<
698 'a,
699 Apply!(<OptionBrand as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
700 >)
701 ) -> Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>) {
702 fa.flatten()
703 }
704
705 #[document_signature]
709 #[document_type_parameters(
711 "The lifetime of the values.",
712 "The type of the error value.",
713 "The type of the success value."
714 )]
715 #[document_parameters("The option of result.")]
717 #[document_returns("A pair of options.")]
719 #[document_examples]
721 fn separate<'a, E: 'a, O: 'a>(
734 fa: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, Result<O, E>>)
735 ) -> (
736 Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, E>),
737 Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, O>),
738 ) {
739 match fa {
740 Some(Ok(o)) => (None, Some(o)),
741 Some(Err(e)) => (Some(e), None),
742 None => (None, None),
743 }
744 }
745 }
746
747 impl Filterable for OptionBrand {
748 #[document_signature]
752 #[document_type_parameters(
754 "The lifetime of the values.",
755 "The type of the input value.",
756 "The type of the error value.",
757 "The type of the success value."
758 )]
759 #[document_parameters("The function to apply.", "The option to partition.")]
761 #[document_returns("A pair of options.")]
763 #[document_examples]
765 fn partition_map<'a, A: 'a, E: 'a, O: 'a>(
779 func: impl Fn(A) -> Result<O, E> + 'a,
780 fa: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
781 ) -> (
782 Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, E>),
783 Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, O>),
784 ) {
785 match fa {
786 Some(a) => match func(a) {
787 Ok(o) => (None, Some(o)),
788 Err(e) => (Some(e), None),
789 },
790 None => (None, None),
791 }
792 }
793
794 #[document_signature]
798 #[document_type_parameters("The lifetime of the values.", "The type of the elements.")]
800 #[document_parameters("The predicate.", "The option to partition.")]
802 #[document_returns("A pair of options.")]
804 #[document_examples]
806 fn partition<'a, A: 'a + Clone>(
819 func: impl Fn(A) -> bool + 'a,
820 fa: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
821 ) -> (
822 Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
823 Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
824 ) {
825 match fa {
826 Some(a) =>
827 if func(a.clone()) {
828 (None, Some(a))
829 } else {
830 (Some(a), None)
831 },
832 None => (None, None),
833 }
834 }
835
836 #[document_signature]
840 #[document_type_parameters(
842 "The lifetime of the values.",
843 "The type of the input value.",
844 "The type of the result of applying the function."
845 )]
846 #[document_parameters("The function to apply.", "The option to filter and map.")]
848 #[document_returns("The filtered and mapped option.")]
850 #[document_examples]
852 fn filter_map<'a, A: 'a, B: 'a>(
864 func: impl Fn(A) -> Option<B> + 'a,
865 fa: 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 fa.and_then(func)
868 }
869
870 #[document_signature]
874 #[document_type_parameters("The lifetime of the values.", "The type of the elements.")]
876 #[document_parameters("The predicate.", "The option to filter.")]
878 #[document_returns("The filtered option.")]
880 #[document_examples]
882 fn filter<'a, A: 'a + Clone>(
894 func: impl Fn(A) -> bool + 'a,
895 fa: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
896 ) -> Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>) {
897 fa.filter(|a| func(a.clone()))
898 }
899 }
900
901 impl Witherable for OptionBrand {
902 #[document_signature]
906 #[document_type_parameters(
908 "The lifetime of the values.",
909 "The applicative context.",
910 "The type of the elements in the input structure.",
911 "The type of the error values.",
912 "The type of the success values."
913 )]
914 #[document_parameters(
916 "The function to apply to each element, returning a `Result` in an applicative context.",
917 "The option to partition."
918 )]
919 #[document_returns("The partitioned option wrapped in the applicative context.")]
921 #[document_examples]
922 fn wilt<'a, M: Applicative, A: 'a + Clone, E: 'a + Clone, O: 'a + Clone>(
935 func: impl Fn(A) -> Apply!(<M as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, Result<O, E>>)
936 + 'a,
937 ta: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
938 ) -> Apply!(<M as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<
939 'a,
940 (
941 Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, E>),
942 Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, O>),
943 ),
944 >)
945 where
946 Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, Result<O, E>>): Clone,
947 Apply!(<M as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, Result<O, E>>): Clone, {
948 match ta {
949 Some(a) => M::map(
950 |res| match res {
951 Ok(o) => (None, Some(o)),
952 Err(e) => (Some(e), None),
953 },
954 func(a),
955 ),
956 None => M::pure((None, None)),
957 }
958 }
959
960 #[document_signature]
964 #[document_type_parameters(
966 "The lifetime of the values.",
967 "The applicative context.",
968 "The type of the elements in the input structure.",
969 "The type of the result of applying the function."
970 )]
971 #[document_parameters(
973 "The function to apply to each element, returning an `Option` in an applicative context.",
974 "The option to filter and map."
975 )]
976 #[document_returns("The filtered and mapped option wrapped in the applicative context.")]
978 #[document_examples]
979 fn wither<'a, M: Applicative, A: 'a + Clone, B: 'a + Clone>(
994 func: impl Fn(A) -> Apply!(<M as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, Option<B>>) + 'a,
995 ta: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
996 ) -> Apply!(<M as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<
997 'a,
998 Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>),
999 >)
1000 where
1001 Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, Option<B>>): Clone,
1002 Apply!(<M as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, Option<B>>): Clone, {
1003 match ta {
1004 Some(a) => func(a),
1005 None => M::pure(None),
1006 }
1007 }
1008 }
1009}
1010
1011#[cfg(test)]
1012mod tests {
1013
1014 use {
1015 crate::{
1016 brands::*,
1017 classes::CloneableFn,
1018 functions::*,
1019 },
1020 quickcheck_macros::quickcheck,
1021 };
1022
1023 #[quickcheck]
1027 fn functor_identity(x: Option<i32>) -> bool {
1028 map::<OptionBrand, _, _>(identity, x) == x
1029 }
1030
1031 #[quickcheck]
1033 fn functor_composition(x: Option<i32>) -> bool {
1034 let f = |x: i32| x.wrapping_add(1);
1035 let g = |x: i32| x.wrapping_mul(2);
1036 map::<OptionBrand, _, _>(compose(f, g), x)
1037 == map::<OptionBrand, _, _>(f, map::<OptionBrand, _, _>(g, x))
1038 }
1039
1040 #[quickcheck]
1044 fn applicative_identity(v: Option<i32>) -> bool {
1045 apply::<RcFnBrand, OptionBrand, _, _>(
1046 pure::<OptionBrand, _>(<RcFnBrand as CloneableFn>::new(identity)),
1047 v,
1048 ) == v
1049 }
1050
1051 #[quickcheck]
1053 fn applicative_homomorphism(x: i32) -> bool {
1054 let f = |x: i32| x.wrapping_mul(2);
1055 apply::<RcFnBrand, OptionBrand, _, _>(
1056 pure::<OptionBrand, _>(<RcFnBrand as CloneableFn>::new(f)),
1057 pure::<OptionBrand, _>(x),
1058 ) == pure::<OptionBrand, _>(f(x))
1059 }
1060
1061 #[quickcheck]
1063 fn applicative_composition(
1064 w: Option<i32>,
1065 u_is_some: bool,
1066 v_is_some: bool,
1067 ) -> bool {
1068 let v_fn = |x: i32| x.wrapping_mul(2);
1069 let u_fn = |x: i32| x.wrapping_add(1);
1070
1071 let v = if v_is_some {
1072 pure::<OptionBrand, _>(<RcFnBrand as CloneableFn>::new(v_fn))
1073 } else {
1074 None
1075 };
1076 let u = if u_is_some {
1077 pure::<OptionBrand, _>(<RcFnBrand as CloneableFn>::new(u_fn))
1078 } else {
1079 None
1080 };
1081
1082 let vw = apply::<RcFnBrand, OptionBrand, _, _>(v.clone(), w);
1084 let rhs = apply::<RcFnBrand, OptionBrand, _, _>(u.clone(), vw);
1085
1086 let uv = match (u, v) {
1089 (Some(uf), Some(vf)) => {
1090 let composed = move |x| uf(vf(x));
1091 Some(<RcFnBrand as CloneableFn>::new(composed))
1092 }
1093 _ => None,
1094 };
1095
1096 let lhs = apply::<RcFnBrand, OptionBrand, _, _>(uv, w);
1097
1098 lhs == rhs
1099 }
1100
1101 #[quickcheck]
1103 fn applicative_interchange(y: i32) -> bool {
1104 let f = |x: i32| x.wrapping_mul(2);
1106 let u = pure::<OptionBrand, _>(<RcFnBrand as CloneableFn>::new(f));
1107
1108 let lhs = apply::<RcFnBrand, OptionBrand, _, _>(u.clone(), pure::<OptionBrand, _>(y));
1109
1110 let rhs_fn =
1111 <RcFnBrand as CloneableFn>::new(move |f: std::rc::Rc<dyn Fn(i32) -> i32>| f(y));
1112 let rhs = apply::<RcFnBrand, OptionBrand, _, _>(pure::<OptionBrand, _>(rhs_fn), u);
1113
1114 lhs == rhs
1115 }
1116
1117 #[quickcheck]
1121 fn monad_left_identity(a: i32) -> bool {
1122 let f = |x: i32| Some(x.wrapping_mul(2));
1123 bind::<OptionBrand, _, _>(pure::<OptionBrand, _>(a), f) == f(a)
1124 }
1125
1126 #[quickcheck]
1128 fn monad_right_identity(m: Option<i32>) -> bool {
1129 bind::<OptionBrand, _, _>(m, pure::<OptionBrand, _>) == m
1130 }
1131
1132 #[quickcheck]
1134 fn monad_associativity(m: Option<i32>) -> bool {
1135 let f = |x: i32| Some(x.wrapping_mul(2));
1136 let g = |x: i32| Some(x.wrapping_add(1));
1137 bind::<OptionBrand, _, _>(bind::<OptionBrand, _, _>(m, f), g)
1138 == bind::<OptionBrand, _, _>(m, |x| bind::<OptionBrand, _, _>(f(x), g))
1139 }
1140
1141 #[test]
1145 fn map_none() {
1146 assert_eq!(map::<OptionBrand, _, _>(|x: i32| x + 1, None), None);
1147 }
1148
1149 #[test]
1151 fn bind_none() {
1152 assert_eq!(bind::<OptionBrand, _, _>(None, |x: i32| Some(x + 1)), None);
1153 }
1154
1155 #[test]
1157 fn bind_returning_none() {
1158 assert_eq!(bind::<OptionBrand, _, _>(Some(5), |_| None::<i32>), None);
1159 }
1160
1161 #[test]
1163 fn fold_right_none() {
1164 assert_eq!(
1165 crate::classes::foldable::fold_right::<RcFnBrand, OptionBrand, _, _>(
1166 |x: i32, acc| x + acc,
1167 0,
1168 None
1169 ),
1170 0
1171 );
1172 }
1173
1174 #[test]
1176 fn fold_left_none() {
1177 assert_eq!(
1178 crate::classes::foldable::fold_left::<RcFnBrand, OptionBrand, _, _>(
1179 |acc, x: i32| acc + x,
1180 0,
1181 None
1182 ),
1183 0
1184 );
1185 }
1186
1187 #[test]
1189 fn traverse_none() {
1190 assert_eq!(
1191 crate::classes::traversable::traverse::<OptionBrand, _, _, OptionBrand>(
1192 |x: i32| Some(x + 1),
1193 None
1194 ),
1195 Some(None)
1196 );
1197 }
1198
1199 #[test]
1201 fn traverse_returning_none() {
1202 assert_eq!(
1203 crate::classes::traversable::traverse::<OptionBrand, _, _, OptionBrand>(
1204 |_: i32| None::<i32>,
1205 Some(5)
1206 ),
1207 None
1208 );
1209 }
1210
1211 #[test]
1215 fn par_fold_map_none() {
1216 let x: Option<i32> = None;
1217 let f = send_cloneable_fn_new::<ArcFnBrand, _, _>(|x: i32| x.to_string());
1218 assert_eq!(par_fold_map::<ArcFnBrand, OptionBrand, _, _>(f, x), "".to_string());
1219 }
1220
1221 #[test]
1223 fn par_fold_map_some() {
1224 let x = Some(5);
1225 let f = send_cloneable_fn_new::<ArcFnBrand, _, _>(|x: i32| x.to_string());
1226 assert_eq!(par_fold_map::<ArcFnBrand, OptionBrand, _, _>(f, x), "5".to_string());
1227 }
1228
1229 #[test]
1231 fn par_fold_right_some() {
1232 let x = Some(5);
1233 let f = send_cloneable_fn_new::<ArcFnBrand, _, _>(|(a, b): (i32, i32)| a + b);
1234 assert_eq!(par_fold_right::<ArcFnBrand, OptionBrand, _, _>(f, 10, x), 15);
1235 }
1236
1237 #[quickcheck]
1241 fn filterable_filter_map_identity(x: Option<Option<i32>>) -> bool {
1242 filter_map::<OptionBrand, _, _>(identity, x) == compact::<OptionBrand, _>(x)
1243 }
1244
1245 #[quickcheck]
1247 fn filterable_filter_map_just(x: Option<i32>) -> bool {
1248 filter_map::<OptionBrand, _, _>(Some, x) == x
1249 }
1250
1251 #[quickcheck]
1253 fn filterable_filter_map_composition(x: Option<i32>) -> bool {
1254 let r = |i: i32| if i % 2 == 0 { Some(i) } else { None };
1255 let l = |i: i32| if i > 5 { Some(i) } else { None };
1256 let composed = |i| r(i).and_then(l);
1257
1258 filter_map::<OptionBrand, _, _>(composed, x)
1259 == filter_map::<OptionBrand, _, _>(l, filter_map::<OptionBrand, _, _>(r, x))
1260 }
1261
1262 #[quickcheck]
1264 fn filterable_filter_consistency(x: Option<i32>) -> bool {
1265 let p = |i: i32| i % 2 == 0;
1266 let maybe_bool = |i| if p(i) { Some(i) } else { None };
1267
1268 filter::<OptionBrand, _>(p, x) == filter_map::<OptionBrand, _, _>(maybe_bool, x)
1269 }
1270
1271 #[quickcheck]
1273 fn filterable_partition_map_identity(x: Option<Result<i32, i32>>) -> bool {
1274 partition_map::<OptionBrand, _, _, _>(identity, x) == separate::<OptionBrand, _, _>(x)
1275 }
1276
1277 #[quickcheck]
1279 fn filterable_partition_map_right_identity(x: Option<i32>) -> bool {
1280 let (_, oks) = partition_map::<OptionBrand, _, _, _>(Ok::<_, i32>, x);
1281 oks == x
1282 }
1283
1284 #[quickcheck]
1286 fn filterable_partition_map_left_identity(x: Option<i32>) -> bool {
1287 let (errs, _) = partition_map::<OptionBrand, _, _, _>(Err::<i32, _>, x);
1288 errs == x
1289 }
1290
1291 #[quickcheck]
1293 fn filterable_partition_consistency(x: Option<i32>) -> bool {
1294 let p = |i: i32| i % 2 == 0;
1295 let either_bool = |i| if p(i) { Ok(i) } else { Err(i) };
1296
1297 let (not_satisfied, satisfied) = partition::<OptionBrand, _>(p, x);
1298 let (errs, oks) = partition_map::<OptionBrand, _, _, _>(either_bool, x);
1299
1300 satisfied == oks && not_satisfied == errs
1301 }
1302
1303 #[quickcheck]
1307 fn witherable_identity(x: Option<i32>) -> bool {
1308 wither::<OptionBrand, OptionBrand, _, _>(|i| Some(Some(i)), x) == Some(x)
1309 }
1310
1311 #[quickcheck]
1313 fn witherable_wilt_consistency(x: Option<i32>) -> bool {
1314 let p = |i: i32| Some(if i % 2 == 0 { Ok(i) } else { Err(i) });
1315
1316 let lhs = wilt::<OptionBrand, OptionBrand, _, _, _>(p, x);
1317 let rhs = map::<OptionBrand, _, _>(
1318 separate::<OptionBrand, _, _>,
1319 traverse::<OptionBrand, _, _, OptionBrand>(p, x),
1320 );
1321
1322 lhs == rhs
1323 }
1324
1325 #[quickcheck]
1327 fn witherable_wither_consistency(x: Option<i32>) -> bool {
1328 let p = |i: i32| Some(if i % 2 == 0 { Some(i) } else { None });
1329
1330 let lhs = wither::<OptionBrand, OptionBrand, _, _>(p, x);
1331 let rhs = map::<OptionBrand, _, _>(
1332 compact::<OptionBrand, _>,
1333 traverse::<OptionBrand, _, _, OptionBrand>(p, x),
1334 );
1335
1336 lhs == rhs
1337 }
1338
1339 #[quickcheck]
1343 fn alt_associativity(
1344 x: Option<i32>,
1345 y: Option<i32>,
1346 z: Option<i32>,
1347 ) -> bool {
1348 alt::<OptionBrand, _>(alt::<OptionBrand, _>(x, y), z)
1349 == alt::<OptionBrand, _>(x, alt::<OptionBrand, _>(y, z))
1350 }
1351
1352 #[quickcheck]
1354 fn alt_distributivity(
1355 x: Option<i32>,
1356 y: Option<i32>,
1357 ) -> bool {
1358 let f = |i: i32| i.wrapping_mul(2).wrapping_add(1);
1359 map::<OptionBrand, _, _>(f, alt::<OptionBrand, _>(x, y))
1360 == alt::<OptionBrand, _>(map::<OptionBrand, _, _>(f, x), map::<OptionBrand, _, _>(f, y))
1361 }
1362
1363 #[quickcheck]
1367 fn plus_left_identity(x: Option<i32>) -> bool {
1368 alt::<OptionBrand, _>(plus_empty::<OptionBrand, i32>(), x) == x
1369 }
1370
1371 #[quickcheck]
1373 fn plus_right_identity(x: Option<i32>) -> bool {
1374 alt::<OptionBrand, _>(x, plus_empty::<OptionBrand, i32>()) == x
1375 }
1376
1377 #[test]
1379 fn plus_annihilation() {
1380 let f = |i: i32| i.wrapping_mul(2);
1381 assert_eq!(
1382 map::<OptionBrand, _, _>(f, plus_empty::<OptionBrand, i32>()),
1383 plus_empty::<OptionBrand, i32>(),
1384 );
1385 }
1386
1387 #[quickcheck]
1391 fn compactable_functor_identity(fa: Option<i32>) -> bool {
1392 compact::<OptionBrand, _>(map::<OptionBrand, _, _>(Some, fa)) == fa
1393 }
1394
1395 #[test]
1397 fn compactable_plus_annihilation_empty() {
1398 assert_eq!(
1399 compact::<OptionBrand, _>(plus_empty::<OptionBrand, Option<i32>>()),
1400 plus_empty::<OptionBrand, i32>(),
1401 );
1402 }
1403
1404 #[quickcheck]
1406 fn compactable_plus_annihilation_map(xs: Option<i32>) -> bool {
1407 compact::<OptionBrand, _>(map::<OptionBrand, _, _>(|_: i32| None::<i32>, xs))
1408 == plus_empty::<OptionBrand, i32>()
1409 }
1410
1411 #[test]
1415 fn compact_some_none() {
1416 assert_eq!(compact::<OptionBrand, _>(Some(None::<i32>)), None);
1417 }
1418
1419 #[test]
1421 fn compact_some_some() {
1422 assert_eq!(compact::<OptionBrand, _>(Some(Some(5))), Some(5));
1423 }
1424
1425 #[test]
1427 fn compact_none() {
1428 assert_eq!(compact::<OptionBrand, _>(None::<Option<i32>>), None);
1429 }
1430
1431 #[test]
1433 fn separate_some_ok() {
1434 let (errs, oks) = separate::<OptionBrand, _, _>(Some(Ok::<i32, &str>(5)));
1435 assert_eq!(oks, Some(5));
1436 assert_eq!(errs, None);
1437 }
1438
1439 #[test]
1441 fn separate_some_err() {
1442 let (errs, oks) = separate::<OptionBrand, _, _>(Some(Err::<i32, &str>("error")));
1443 assert_eq!(oks, None);
1444 assert_eq!(errs, Some("error"));
1445 }
1446
1447 #[test]
1449 fn separate_none() {
1450 let (errs, oks) = separate::<OptionBrand, _, _>(None::<Result<i32, &str>>);
1451 assert_eq!(oks, None);
1452 assert_eq!(errs, None);
1453 }
1454
1455 #[test]
1457 fn partition_map_none() {
1458 let (errs, oks) =
1459 partition_map::<OptionBrand, _, _, _>(|x: i32| Ok::<i32, i32>(x), None::<i32>);
1460 assert_eq!(oks, None);
1461 assert_eq!(errs, None);
1462 }
1463
1464 #[test]
1466 fn partition_none() {
1467 let (not_satisfied, satisfied) = partition::<OptionBrand, _>(|x: i32| x > 0, None::<i32>);
1468 assert_eq!(satisfied, None);
1469 assert_eq!(not_satisfied, None);
1470 }
1471
1472 #[test]
1474 fn filter_map_none() {
1475 assert_eq!(filter_map::<OptionBrand, _, _>(|x: i32| Some(x), None::<i32>), None);
1476 }
1477
1478 #[test]
1480 fn filter_none() {
1481 assert_eq!(filter::<OptionBrand, _>(|x: i32| x > 0, None::<i32>), None);
1482 }
1483
1484 #[test]
1486 fn wilt_none() {
1487 let res = wilt::<OptionBrand, OptionBrand, _, _, _>(
1488 |x: i32| Some(Ok::<i32, i32>(x)),
1489 None::<i32>,
1490 );
1491 assert_eq!(res, Some((None, None)));
1492 }
1493
1494 #[test]
1496 fn wither_none() {
1497 let res = wither::<OptionBrand, OptionBrand, _, _>(|x: i32| Some(Some(x)), None::<i32>);
1498 assert_eq!(res, Some(None));
1499 }
1500}