1#[fp_macros::document_module]
6mod inner {
7 use {
8 crate::{
9 Apply,
10 brands::OptionBrand,
11 classes::*,
12 dispatch::Ref,
13 impl_kind,
14 kinds::*,
15 },
16 core::ops::ControlFlow,
17 fp_macros::*,
18 };
19
20 impl_kind! {
21 for OptionBrand {
22 type Of<'a, A: 'a>: 'a = Option<A>;
23 }
24 }
25
26 impl Functor for OptionBrand {
27 #[document_signature]
31 #[document_type_parameters(
33 "The lifetime of the value.",
34 "The type of the value inside the option.",
35 "The type of the result of applying the function."
36 )]
37 #[document_parameters("The function to apply to the value.", "The option to map over.")]
39 #[document_returns(
41 "A new option containing the result of applying the function, or `None`."
42 )]
43 #[document_examples]
45 fn map<'a, A: 'a, B: 'a>(
57 func: impl Fn(A) -> B + 'a,
58 fa: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
59 ) -> Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>) {
60 fa.map(func)
61 }
62 }
63
64 impl Lift for OptionBrand {
65 #[document_signature]
69 #[document_type_parameters(
71 "The lifetime of the values.",
72 "The type of the first option's value.",
73 "The type of the second option's value.",
74 "The return type of the function."
75 )]
76 #[document_parameters(
78 "The binary function to apply.",
79 "The first option.",
80 "The second option."
81 )]
82 #[document_returns("`Some(f(a, b))` if both options are `Some`, otherwise `None`.")]
84 #[document_examples]
85 fn lift2<'a, A, B, C>(
98 func: impl Fn(A, B) -> C + 'a,
99 fa: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
100 fb: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>),
101 ) -> Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, C>)
102 where
103 A: 'a,
104 B: 'a,
105 C: 'a, {
106 fa.zip(fb).map(|(a, b)| func(a, b))
107 }
108 }
109
110 impl Pointed for OptionBrand {
111 #[document_signature]
115 #[document_type_parameters("The lifetime of the value.", "The type of the value to wrap.")]
117 #[document_parameters("The value to wrap.")]
119 #[document_returns("`Some(a)`.")]
121 #[document_examples]
123 fn pure<'a, A: 'a>(a: A) -> Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>) {
134 Some(a)
135 }
136 }
137
138 impl ApplyFirst for OptionBrand {}
139 impl ApplySecond for OptionBrand {}
140
141 impl Semiapplicative for OptionBrand {
142 #[document_signature]
146 #[document_type_parameters(
148 "The lifetime of the values.",
149 "The brand of the cloneable function wrapper.",
150 "The type of the input value.",
151 "The type of the output value."
152 )]
153 #[document_parameters(
155 "The option containing the function.",
156 "The option containing the value."
157 )]
158 #[document_returns("`Some(f(a))` if both are `Some`, otherwise `None`.")]
160 #[document_examples]
161 fn apply<'a, FnBrand: 'a + CloneFn, A: 'a + Clone, B: 'a>(
175 ff: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, <FnBrand as CloneFn>::Of<'a, A, B>>),
176 fa: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
177 ) -> Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>) {
178 match (ff, fa) {
179 (Some(f), Some(a)) => Some(f(a)),
180 _ => None,
181 }
182 }
183 }
184
185 impl Semimonad for OptionBrand {
186 #[document_signature]
190 #[document_type_parameters(
192 "The lifetime of the values.",
193 "The type of the result of the first computation.",
194 "The type of the result of the second computation."
195 )]
196 #[document_parameters(
198 "The first option.",
199 "The function to apply to the value inside the option."
200 )]
201 #[document_returns(
203 "The result of applying `f` to the value if `ma` is `Some`, otherwise `None`."
204 )]
205 #[document_examples]
206 fn bind<'a, A: 'a, B: 'a>(
218 ma: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
219 func: impl Fn(A) -> Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>) + 'a,
220 ) -> Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>) {
221 ma.and_then(func)
222 }
223 }
224
225 impl Alt for OptionBrand {
226 #[document_signature]
230 #[document_type_parameters("The lifetime of the values.", "The type of the value.")]
232 #[document_parameters("The first option.", "The second option.")]
234 #[document_returns("The first `Some` value, or `None`.")]
236 #[document_examples]
237 fn alt<'a, A: 'a>(
250 fa1: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
251 fa2: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
252 ) -> Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>) {
253 fa1.or(fa2)
254 }
255 }
256
257 impl RefAlt for OptionBrand {
258 #[document_signature]
264 #[document_type_parameters("The lifetime of the values.", "The type of the value.")]
266 #[document_parameters("The first option.", "The second option.")]
268 #[document_returns("The first `Some` value (cloned), or `None`.")]
270 #[document_examples]
271 fn ref_alt<'a, A: 'a + Clone>(
284 fa1: &Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
285 fa2: &Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
286 ) -> Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>) {
287 fa1.as_ref().or(fa2.as_ref()).cloned()
288 }
289 }
290
291 impl Plus for OptionBrand {
292 #[document_signature]
294 #[document_type_parameters("The lifetime of the value.", "The type of the value.")]
296 #[document_returns("`None`.")]
298 #[document_examples]
299 fn empty<'a, A: 'a>() -> Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>) {
310 None
311 }
312 }
313
314 impl Foldable for OptionBrand {
315 #[document_signature]
319 #[document_type_parameters(
321 "The lifetime of the values.",
322 "The brand of the cloneable function to use.",
323 "The type of the elements in the structure.",
324 "The type of the accumulator."
325 )]
326 #[document_parameters("The folding function.", "The initial value.", "The option to fold.")]
328 #[document_returns("`func(a, initial)` if `fa` is `Some(a)`, otherwise `initial`.")]
330 #[document_examples]
332 fn fold_right<'a, FnBrand, A: 'a + Clone, B: 'a>(
344 func: impl Fn(A, B) -> B + 'a,
345 initial: B,
346 fa: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
347 ) -> B
348 where
349 FnBrand: CloneFn + 'a, {
350 match fa {
351 Some(a) => func(a, initial),
352 None => initial,
353 }
354 }
355
356 #[document_signature]
360 #[document_type_parameters(
362 "The lifetime of the values.",
363 "The brand of the cloneable function to use.",
364 "The type of the elements in the structure.",
365 "The type of the accumulator."
366 )]
367 #[document_parameters(
369 "The function to apply to the accumulator and each element.",
370 "The initial value of the accumulator.",
371 "The option to fold."
372 )]
373 #[document_returns("`f(initial, a)` if `fa` is `Some(a)`, otherwise `initial`.")]
375 #[document_examples]
376 fn fold_left<'a, FnBrand, A: 'a + Clone, B: 'a>(
388 func: impl Fn(B, A) -> B + 'a,
389 initial: B,
390 fa: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
391 ) -> B
392 where
393 FnBrand: CloneFn + 'a, {
394 match fa {
395 Some(a) => func(initial, a),
396 None => initial,
397 }
398 }
399
400 #[document_signature]
404 #[document_type_parameters(
406 "The lifetime of the values.",
407 "The brand of the cloneable function to use.",
408 "The type of the elements in the structure.",
409 "The type of the monoid."
410 )]
411 #[document_parameters("The mapping function.", "The option to fold.")]
413 #[document_returns("`func(a)` if `fa` is `Some(a)`, otherwise `M::empty()`.")]
415 #[document_examples]
417 fn fold_map<'a, FnBrand, A: 'a + Clone, M>(
429 func: impl Fn(A) -> M + 'a,
430 fa: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
431 ) -> M
432 where
433 M: Monoid + 'a,
434 FnBrand: CloneFn + 'a, {
435 match fa {
436 Some(a) => func(a),
437 None => M::empty(),
438 }
439 }
440 }
441
442 impl Traversable for OptionBrand {
443 #[document_signature]
447 #[document_type_parameters(
449 "The lifetime of the values.",
450 "The type of the elements in the traversable structure.",
451 "The type of the elements in the resulting traversable structure.",
452 "The applicative context."
453 )]
454 #[document_parameters(
456 "The function to apply to each element, returning a value in an applicative context.",
457 "The option to traverse."
458 )]
459 #[document_returns("The option wrapped in the applicative context.")]
461 #[document_examples]
462 fn traverse<'a, A: 'a + Clone, B: 'a + Clone, F: Applicative>(
475 func: impl Fn(A) -> Apply!(<F as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>) + 'a,
476 ta: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
477 ) -> 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>)>)
478 where
479 Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>): Clone, {
480 match ta {
481 Some(a) => F::map(|b| Some(b), func(a)),
482 None => F::pure(None),
483 }
484 }
485
486 #[document_signature]
490 #[document_type_parameters(
492 "The lifetime of the values.",
493 "The type of the elements in the traversable structure.",
494 "The applicative context."
495 )]
496 #[document_parameters("The option containing the applicative value.")]
498 #[document_returns("The result of the traversal.")]
500 #[document_examples]
505 fn sequence<'a, A: 'a + Clone, F: Applicative>(
517 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>)>)
518 ) -> 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>)>)
519 where
520 Apply!(<F as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>): Clone,
521 Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>): Clone, {
522 match ta {
523 Some(fa) => F::map(|a| Some(a), fa),
524 None => F::pure(None),
525 }
526 }
527 }
528
529 impl WithIndex for OptionBrand {
530 type Index = ();
531 }
532
533 impl FunctorWithIndex for OptionBrand {
534 #[document_signature]
536 #[document_type_parameters(
537 "The lifetime of the value.",
538 "The type of the value inside the option.",
539 "The type of the result of applying the function."
540 )]
541 #[document_parameters(
542 "The function to apply to the value and its index.",
543 "The option to map over."
544 )]
545 #[document_returns(
546 "A new option containing the result of applying the function, or `None`."
547 )]
548 #[document_examples]
549 fn map_with_index<'a, A: 'a, B: 'a>(
561 f: impl Fn((), A) -> B + 'a,
562 fa: Option<A>,
563 ) -> Option<B> {
564 fa.map(|a| f((), a))
565 }
566 }
567
568 impl FoldableWithIndex for OptionBrand {
569 #[document_signature]
571 #[document_type_parameters(
572 "The lifetime of the value.",
573 "The brand of the cloneable function to use.",
574 "The type of the value inside the option.",
575 "The monoid type."
576 )]
577 #[document_parameters(
578 "The function to apply to the value and its index.",
579 "The option to fold."
580 )]
581 #[document_returns("The monoid value.")]
582 #[document_examples]
583 fn fold_map_with_index<'a, FnBrand, A: 'a + Clone, R: Monoid + 'a>(
598 f: impl Fn((), A) -> R + 'a,
599 fa: Option<A>,
600 ) -> R
601 where
602 FnBrand: LiftFn + 'a, {
603 match fa {
604 Some(a) => f((), a),
605 None => R::empty(),
606 }
607 }
608 }
609
610 impl TraversableWithIndex for OptionBrand {
611 #[document_signature]
613 #[document_type_parameters(
614 "The lifetime of the value.",
615 "The type of the value inside the option.",
616 "The type of the result.",
617 "The applicative context."
618 )]
619 #[document_parameters(
620 "The function to apply to the value and its index, returning a value in an applicative context.",
621 "The option to traverse."
622 )]
623 #[document_returns("The option wrapped in the applicative context.")]
624 #[document_examples]
625 fn traverse_with_index<'a, A: 'a, B: 'a + Clone, M: Applicative>(
640 f: impl Fn((), A) -> M::Of<'a, B> + 'a,
641 ta: Option<A>,
642 ) -> M::Of<'a, Option<B>> {
643 match ta {
644 Some(a) => M::map(|b| Some(b), f((), a)),
645 None => M::pure(None),
646 }
647 }
648 }
649
650 impl Compactable for OptionBrand {
651 #[document_signature]
655 #[document_type_parameters("The lifetime of the values.", "The type of the elements.")]
657 #[document_parameters("The nested option.")]
659 #[document_returns("The flattened option.")]
661 #[document_examples]
663 fn compact<'a, A: 'a>(
675 fa: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<
676 'a,
677 Apply!(<OptionBrand as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
678 >)
679 ) -> Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>) {
680 fa.flatten()
681 }
682
683 #[document_signature]
687 #[document_type_parameters(
689 "The lifetime of the values.",
690 "The type of the error value.",
691 "The type of the success value."
692 )]
693 #[document_parameters("The option of result.")]
695 #[document_returns("A pair of options.")]
697 #[document_examples]
699 fn separate<'a, E: 'a, O: 'a>(
712 fa: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, Result<O, E>>)
713 ) -> (
714 Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, E>),
715 Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, O>),
716 ) {
717 match fa {
718 Some(Ok(o)) => (None, Some(o)),
719 Some(Err(e)) => (Some(e), None),
720 None => (None, None),
721 }
722 }
723 }
724
725 impl RefCompactable for OptionBrand {
726 #[document_signature]
731 #[document_type_parameters(
733 "The lifetime of the values.",
734 "The type of the elements. Must be [`Clone`] because elements are extracted from a borrowed container."
735 )]
736 #[document_parameters("A reference to the nested option.")]
738 #[document_returns("The flattened option with the inner value cloned, or [`None`].")]
740 #[document_examples]
742 fn ref_compact<'a, A: 'a + Clone>(
758 fa: &Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, Option<A>>)
759 ) -> Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>) {
760 match fa {
761 Some(Some(a)) => Some(a.clone()),
762 _ => None,
763 }
764 }
765
766 #[document_signature]
772 #[document_type_parameters(
774 "The lifetime of the values.",
775 "The type of the error value. Must be [`Clone`] because elements are extracted from a borrowed container.",
776 "The type of the success value. Must be [`Clone`] because elements are extracted from a borrowed container."
777 )]
778 #[document_parameters("A reference to the option of result.")]
780 #[document_returns(
782 "A pair of options: the first containing the cloned error, the second containing the cloned success value."
783 )]
784 #[document_examples]
786 fn ref_separate<'a, E: 'a + Clone, O: 'a + Clone>(
804 fa: &Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, Result<O, E>>)
805 ) -> (
806 Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, E>),
807 Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, O>),
808 ) {
809 match fa {
810 Some(Ok(o)) => (None, Some(o.clone())),
811 Some(Err(e)) => (Some(e.clone()), None),
812 None => (None, None),
813 }
814 }
815 }
816
817 impl Filterable for OptionBrand {
818 #[document_signature]
822 #[document_type_parameters(
824 "The lifetime of the values.",
825 "The type of the input value.",
826 "The type of the error value.",
827 "The type of the success value."
828 )]
829 #[document_parameters("The function to apply.", "The option to partition.")]
831 #[document_returns("A pair of options.")]
833 #[document_examples]
835 fn partition_map<'a, A: 'a, E: 'a, O: 'a>(
851 func: impl Fn(A) -> Result<O, E> + 'a,
852 fa: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
853 ) -> (
854 Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, E>),
855 Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, O>),
856 ) {
857 match fa {
858 Some(a) => match func(a) {
859 Ok(o) => (None, Some(o)),
860 Err(e) => (Some(e), None),
861 },
862 None => (None, None),
863 }
864 }
865
866 #[document_signature]
870 #[document_type_parameters("The lifetime of the values.", "The type of the elements.")]
872 #[document_parameters("The predicate.", "The option to partition.")]
874 #[document_returns("A pair of options.")]
876 #[document_examples]
878 fn partition<'a, A: 'a + Clone>(
891 func: impl Fn(A) -> bool + 'a,
892 fa: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
893 ) -> (
894 Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
895 Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
896 ) {
897 match fa {
898 Some(a) =>
899 if func(a.clone()) {
900 (None, Some(a))
901 } else {
902 (Some(a), None)
903 },
904 None => (None, None),
905 }
906 }
907
908 #[document_signature]
912 #[document_type_parameters(
914 "The lifetime of the values.",
915 "The type of the input value.",
916 "The type of the result of applying the function."
917 )]
918 #[document_parameters("The function to apply.", "The option to filter and map.")]
920 #[document_returns("The filtered and mapped option.")]
922 #[document_examples]
924 fn filter_map<'a, A: 'a, B: 'a>(
939 func: impl Fn(A) -> Option<B> + 'a,
940 fa: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
941 ) -> Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>) {
942 fa.and_then(func)
943 }
944
945 #[document_signature]
949 #[document_type_parameters("The lifetime of the values.", "The type of the elements.")]
951 #[document_parameters("The predicate.", "The option to filter.")]
953 #[document_returns("The filtered option.")]
955 #[document_examples]
957 fn filter<'a, A: 'a + Clone>(
969 func: impl Fn(A) -> bool + 'a,
970 fa: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
971 ) -> Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>) {
972 fa.filter(|a| func(a.clone()))
973 }
974 }
975
976 impl Witherable for OptionBrand {
977 #[document_signature]
981 #[document_type_parameters(
983 "The lifetime of the values.",
984 "The applicative context.",
985 "The type of the elements in the input structure.",
986 "The type of the error values.",
987 "The type of the success values."
988 )]
989 #[document_parameters(
991 "The function to apply to each element, returning a `Result` in an applicative context.",
992 "The option to partition."
993 )]
994 #[document_returns("The partitioned option wrapped in the applicative context.")]
996 #[document_examples]
997 fn wilt<'a, M: Applicative, A: 'a + Clone, E: 'a + Clone, O: 'a + Clone>(
1012 func: impl Fn(A) -> Apply!(<M as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, Result<O, E>>)
1013 + 'a,
1014 ta: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
1015 ) -> Apply!(<M as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<
1016 'a,
1017 (
1018 Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, E>),
1019 Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, O>),
1020 ),
1021 >)
1022 where
1023 Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, Result<O, E>>): Clone,
1024 Apply!(<M as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, Result<O, E>>): Clone, {
1025 match ta {
1026 Some(a) => M::map(
1027 |res| match res {
1028 Ok(o) => (None, Some(o)),
1029 Err(e) => (Some(e), None),
1030 },
1031 func(a),
1032 ),
1033 None => M::pure((None, None)),
1034 }
1035 }
1036
1037 #[document_signature]
1041 #[document_type_parameters(
1043 "The lifetime of the values.",
1044 "The applicative context.",
1045 "The type of the elements in the input structure.",
1046 "The type of the result of applying the function."
1047 )]
1048 #[document_parameters(
1050 "The function to apply to each element, returning an `Option` in an applicative context.",
1051 "The option to filter and map."
1052 )]
1053 #[document_returns("The filtered and mapped option wrapped in the applicative context.")]
1055 #[document_examples]
1056 fn wither<'a, M: Applicative, A: 'a + Clone, B: 'a + Clone>(
1071 func: impl Fn(A) -> Apply!(<M as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, Option<B>>) + 'a,
1072 ta: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
1073 ) -> Apply!(<M as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<
1074 'a,
1075 Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>),
1076 >)
1077 where
1078 Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, Option<B>>): Clone,
1079 Apply!(<M as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, Option<B>>): Clone, {
1080 match ta {
1081 Some(a) => func(a),
1082 None => M::pure(None),
1083 }
1084 }
1085 }
1086
1087 impl MonadRec for OptionBrand {
1088 #[document_signature]
1095 #[document_type_parameters(
1097 "The lifetime of the computation.",
1098 "The type of the initial value and loop state.",
1099 "The type of the result."
1100 )]
1101 #[document_parameters("The step function.", "The initial value.")]
1103 #[document_returns(
1105 "The result of the computation, or `None` if the step function returned `None`."
1106 )]
1107 #[document_examples]
1109 fn tail_rec_m<'a, A: 'a, B: 'a>(
1129 func: impl Fn(
1130 A,
1131 )
1132 -> Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, ControlFlow<B, A>>)
1133 + 'a,
1134 initial: A,
1135 ) -> Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>) {
1136 let mut current = initial;
1137 loop {
1138 match func(current) {
1139 None => return None,
1140 Some(ControlFlow::Continue(next)) => current = next,
1141 Some(ControlFlow::Break(b)) => return Some(b),
1142 }
1143 }
1144 }
1145 }
1146
1147 impl RefFunctor for OptionBrand {
1150 #[document_signature]
1152 #[document_type_parameters("The lifetime.", "The input type.", "The output type.")]
1153 #[document_parameters("The function.", "The option.")]
1154 #[document_returns("The mapped option.")]
1155 #[document_examples]
1156 fn ref_map<'a, A: 'a, B: 'a>(
1165 func: impl Fn(&A) -> B + 'a,
1166 fa: &Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
1167 ) -> Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>) {
1168 fa.as_ref().map(func)
1169 }
1170 }
1171
1172 impl RefFoldable for OptionBrand {
1173 #[document_signature]
1175 #[document_type_parameters(
1176 "The lifetime.",
1177 "The brand.",
1178 "The element type.",
1179 "The monoid type."
1180 )]
1181 #[document_parameters("The mapping function.", "The option.")]
1182 #[document_returns("The monoid value.")]
1183 #[document_examples]
1184 fn ref_fold_map<'a, FnBrand, A: 'a + Clone, M>(
1195 func: impl Fn(&A) -> M + 'a,
1196 fa: &Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
1197 ) -> M
1198 where
1199 FnBrand: LiftFn + 'a,
1200 M: Monoid + 'a, {
1201 match fa {
1202 Some(a) => func(a),
1203 None => Monoid::empty(),
1204 }
1205 }
1206 }
1207
1208 impl RefFilterable for OptionBrand {
1209 #[document_signature]
1211 #[document_type_parameters("The lifetime.", "The input type.", "The output type.")]
1212 #[document_parameters("The function.", "The option.")]
1213 #[document_returns("The filtered option.")]
1214 #[document_examples]
1215 fn ref_filter_map<'a, A: 'a, B: 'a>(
1228 func: impl Fn(&A) -> Option<B> + 'a,
1229 fa: &Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
1230 ) -> Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>) {
1231 fa.as_ref().and_then(func)
1232 }
1233 }
1234
1235 impl RefTraversable for OptionBrand {
1236 #[document_signature]
1238 #[document_type_parameters(
1239 "The lifetime.",
1240 "The brand.",
1241 "The input type.",
1242 "The output type.",
1243 "The applicative."
1244 )]
1245 #[document_parameters("The function.", "The option.")]
1246 #[document_returns("The traversed result.")]
1247 #[document_examples]
1248 fn ref_traverse<'a, FnBrand, A: 'a + Clone, B: 'a + Clone, F: Applicative>(
1261 func: impl Fn(&A) -> Apply!(<F as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>) + 'a,
1262 ta: &Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
1263 ) -> 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>)>)
1264 where
1265 FnBrand: LiftFn + 'a,
1266 Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>): Clone,
1267 Apply!(<F as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>): Clone, {
1268 match ta {
1269 Some(a) => F::map(|b| Some(b), func(a)),
1270 None => F::pure(None),
1271 }
1272 }
1273 }
1274
1275 impl RefWitherable for OptionBrand {}
1276
1277 impl RefFunctorWithIndex for OptionBrand {
1278 #[document_signature]
1280 #[document_type_parameters("The lifetime.", "The input type.", "The output type.")]
1281 #[document_parameters("The function.", "The option.")]
1282 #[document_returns("The mapped option.")]
1283 #[document_examples]
1284 fn ref_map_with_index<'a, A: 'a, B: 'a>(
1296 func: impl Fn((), &A) -> B + 'a,
1297 fa: &Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
1298 ) -> Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>) {
1299 fa.as_ref().map(|a| func((), a))
1300 }
1301 }
1302
1303 impl RefFoldableWithIndex for OptionBrand {
1304 #[document_signature]
1306 #[document_type_parameters(
1307 "The lifetime.",
1308 "The brand of the cloneable function.",
1309 "The element type.",
1310 "The monoid type."
1311 )]
1312 #[document_parameters("The function.", "The option.")]
1313 #[document_returns("The monoid value.")]
1314 #[document_examples]
1315 fn ref_fold_map_with_index<'a, FnBrand, A: 'a + Clone, R: Monoid + 'a>(
1328 func: impl Fn((), &A) -> R + 'a,
1329 fa: &Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
1330 ) -> R
1331 where
1332 FnBrand: LiftFn + 'a, {
1333 match fa {
1334 Some(a) => func((), a),
1335 None => Monoid::empty(),
1336 }
1337 }
1338 }
1339
1340 impl RefTraversableWithIndex for OptionBrand {
1341 #[document_signature]
1343 #[document_type_parameters(
1344 "The lifetime.",
1345 "The input type.",
1346 "The output type.",
1347 "The applicative."
1348 )]
1349 #[document_parameters("The function.", "The option.")]
1350 #[document_returns("The traversed result.")]
1351 #[document_examples]
1352 fn ref_traverse_with_index<'a, A: 'a + Clone, B: 'a + Clone, M: Applicative>(
1366 f: impl Fn((), &A) -> Apply!(<M as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>) + 'a,
1367 ta: &Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
1368 ) -> 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>)>)
1369 where
1370 Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>): Clone,
1371 Apply!(<M as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>): Clone, {
1372 match ta {
1373 Some(a) => M::map(|b| Some(b), f((), a)),
1374 None => M::pure(None),
1375 }
1376 }
1377 }
1378
1379 impl RefPointed for OptionBrand {
1382 #[document_signature]
1384 #[document_type_parameters("The lifetime of the value.", "The type of the value.")]
1385 #[document_parameters("The reference to the value to wrap.")]
1386 #[document_returns("A `Some` containing a clone of the value.")]
1387 #[document_examples]
1388 fn ref_pure<'a, A: Clone + 'a>(
1400 a: &A
1401 ) -> Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>) {
1402 Some(a.clone())
1403 }
1404 }
1405
1406 impl RefLift for OptionBrand {
1407 #[document_signature]
1409 #[document_type_parameters(
1410 "The lifetime.",
1411 "First input type.",
1412 "Second input type.",
1413 "Output type."
1414 )]
1415 #[document_parameters("The binary function.", "The first option.", "The second option.")]
1416 #[document_returns("The combined result, or `None` if either input is `None`.")]
1417 #[document_examples]
1418 fn ref_lift2<'a, A: 'a, B: 'a, C: 'a>(
1433 func: impl Fn(&A, &B) -> C + 'a,
1434 fa: &Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
1435 fb: &Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>),
1436 ) -> Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, C>) {
1437 match (fa.as_ref(), fb.as_ref()) {
1438 (Some(a), Some(b)) => Some(func(a, b)),
1439 _ => None,
1440 }
1441 }
1442 }
1443
1444 impl RefSemiapplicative for OptionBrand {
1445 #[document_signature]
1447 #[document_type_parameters(
1448 "The lifetime.",
1449 "The function brand.",
1450 "The input type.",
1451 "The output type."
1452 )]
1453 #[document_parameters(
1454 "The option containing the by-ref function.",
1455 "The option containing the value."
1456 )]
1457 #[document_returns("The result of applying the function, or `None`.")]
1458 #[document_examples]
1459 fn ref_apply<'a, FnBrand: 'a + CloneFn<Ref>, A: 'a, B: 'a>(
1472 ff: &Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, <FnBrand as CloneFn<Ref>>::Of<'a, A, B>>),
1473 fa: &Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
1474 ) -> Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>) {
1475 match (ff, fa.as_ref()) {
1476 (Some(f), Some(a)) => Some((**f)(a)),
1477 _ => None,
1478 }
1479 }
1480 }
1481
1482 impl RefSemimonad for OptionBrand {
1483 #[document_signature]
1485 #[document_type_parameters("The lifetime.", "The input type.", "The output type.")]
1486 #[document_parameters("The input option.", "The function to apply by reference.")]
1487 #[document_returns("The result of applying the function, or `None`.")]
1488 #[document_examples]
1489 fn ref_bind<'a, A: 'a, B: 'a>(
1501 fa: &Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
1502 f: impl Fn(&A) -> Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>) + 'a,
1503 ) -> Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>) {
1504 fa.as_ref().and_then(f)
1505 }
1506 }
1507}
1508
1509#[cfg(test)]
1510mod tests {
1511
1512 use {
1513 crate::{
1514 brands::*,
1515 classes::*,
1516 functions::*,
1517 },
1518 quickcheck_macros::quickcheck,
1519 };
1520
1521 #[quickcheck]
1525 fn functor_identity(x: Option<i32>) -> bool {
1526 explicit::map::<OptionBrand, _, _, _, _>(identity, x) == x
1527 }
1528
1529 #[quickcheck]
1531 fn functor_composition(x: Option<i32>) -> bool {
1532 let f = |x: i32| x.wrapping_add(1);
1533 let g = |x: i32| x.wrapping_mul(2);
1534 explicit::map::<OptionBrand, _, _, _, _>(compose(f, g), x)
1535 == explicit::map::<OptionBrand, _, _, _, _>(
1536 f,
1537 explicit::map::<OptionBrand, _, _, _, _>(g, x),
1538 )
1539 }
1540
1541 #[quickcheck]
1545 fn applicative_identity(v: Option<i32>) -> bool {
1546 apply::<RcFnBrand, OptionBrand, _, _>(
1547 pure::<OptionBrand, _>(<RcFnBrand as LiftFn>::new(identity)),
1548 v,
1549 ) == v
1550 }
1551
1552 #[quickcheck]
1554 fn applicative_homomorphism(x: i32) -> bool {
1555 let f = |x: i32| x.wrapping_mul(2);
1556 apply::<RcFnBrand, OptionBrand, _, _>(
1557 pure::<OptionBrand, _>(<RcFnBrand as LiftFn>::new(f)),
1558 pure::<OptionBrand, _>(x),
1559 ) == pure::<OptionBrand, _>(f(x))
1560 }
1561
1562 #[quickcheck]
1564 fn applicative_composition(
1565 w: Option<i32>,
1566 u_is_some: bool,
1567 v_is_some: bool,
1568 ) -> bool {
1569 let v_fn = |x: i32| x.wrapping_mul(2);
1570 let u_fn = |x: i32| x.wrapping_add(1);
1571
1572 let v =
1573 if v_is_some { pure::<OptionBrand, _>(<RcFnBrand as LiftFn>::new(v_fn)) } else { None };
1574 let u =
1575 if u_is_some { pure::<OptionBrand, _>(<RcFnBrand as LiftFn>::new(u_fn)) } else { None };
1576
1577 let vw = apply::<RcFnBrand, OptionBrand, _, _>(v.clone(), w);
1579 let rhs = apply::<RcFnBrand, OptionBrand, _, _>(u.clone(), vw);
1580
1581 let uv = match (u, v) {
1584 (Some(uf), Some(vf)) => {
1585 let composed = move |x| uf(vf(x));
1586 Some(<RcFnBrand as LiftFn>::new(composed))
1587 }
1588 _ => None,
1589 };
1590
1591 let lhs = apply::<RcFnBrand, OptionBrand, _, _>(uv, w);
1592
1593 lhs == rhs
1594 }
1595
1596 #[quickcheck]
1598 fn applicative_interchange(y: i32) -> bool {
1599 let f = |x: i32| x.wrapping_mul(2);
1601 let u = pure::<OptionBrand, _>(<RcFnBrand as LiftFn>::new(f));
1602
1603 let lhs = apply::<RcFnBrand, OptionBrand, _, _>(u.clone(), pure::<OptionBrand, _>(y));
1604
1605 let rhs_fn = <RcFnBrand as LiftFn>::new(move |f: std::rc::Rc<dyn Fn(i32) -> i32>| f(y));
1606 let rhs = apply::<RcFnBrand, OptionBrand, _, _>(pure::<OptionBrand, _>(rhs_fn), u);
1607
1608 lhs == rhs
1609 }
1610
1611 #[quickcheck]
1615 fn monad_left_identity(a: i32) -> bool {
1616 let f = |x: i32| Some(x.wrapping_mul(2));
1617 explicit::bind::<OptionBrand, _, _, _, _>(pure::<OptionBrand, _>(a), f) == f(a)
1618 }
1619
1620 #[quickcheck]
1622 fn monad_right_identity(m: Option<i32>) -> bool {
1623 explicit::bind::<OptionBrand, _, _, _, _>(m, pure::<OptionBrand, _>) == m
1624 }
1625
1626 #[quickcheck]
1628 fn monad_associativity(m: Option<i32>) -> bool {
1629 let f = |x: i32| Some(x.wrapping_mul(2));
1630 let g = |x: i32| Some(x.wrapping_add(1));
1631 explicit::bind::<OptionBrand, _, _, _, _>(
1632 explicit::bind::<OptionBrand, _, _, _, _>(m, f),
1633 g,
1634 ) == explicit::bind::<OptionBrand, _, _, _, _>(m, |x| {
1635 explicit::bind::<OptionBrand, _, _, _, _>(f(x), g)
1636 })
1637 }
1638
1639 #[test]
1643 fn map_none() {
1644 assert_eq!(explicit::map::<OptionBrand, _, _, _, _>(|x: i32| x + 1, None), None);
1645 }
1646
1647 #[test]
1649 fn bind_none() {
1650 assert_eq!(explicit::bind::<OptionBrand, _, _, _, _>(None, |x: i32| Some(x + 1)), None);
1651 }
1652
1653 #[test]
1655 fn bind_returning_none() {
1656 assert_eq!(explicit::bind::<OptionBrand, _, _, _, _>(Some(5), |_| None::<i32>), None);
1657 }
1658
1659 #[test]
1661 fn fold_right_none() {
1662 assert_eq!(
1663 crate::functions::explicit::fold_right::<RcFnBrand, OptionBrand, _, _, _, _>(
1664 |x: i32, acc| x + acc,
1665 0,
1666 None
1667 ),
1668 0
1669 );
1670 }
1671
1672 #[test]
1674 fn fold_left_none() {
1675 assert_eq!(
1676 crate::functions::explicit::fold_left::<RcFnBrand, OptionBrand, _, _, _, _>(
1677 |acc, x: i32| acc + x,
1678 0,
1679 None
1680 ),
1681 0
1682 );
1683 }
1684
1685 #[test]
1687 fn traverse_none() {
1688 assert_eq!(
1689 crate::classes::traversable::traverse::<OptionBrand, _, _, OptionBrand>(
1690 |x: i32| Some(x + 1),
1691 None
1692 ),
1693 Some(None)
1694 );
1695 }
1696
1697 #[test]
1699 fn traverse_returning_none() {
1700 assert_eq!(
1701 crate::classes::traversable::traverse::<OptionBrand, _, _, OptionBrand>(
1702 |_: i32| None::<i32>,
1703 Some(5)
1704 ),
1705 None
1706 );
1707 }
1708
1709 #[quickcheck]
1713 fn monad_rec_identity(x: i32) -> bool {
1714 use {
1715 crate::classes::monad_rec::tail_rec_m,
1716 core::ops::ControlFlow,
1717 };
1718 tail_rec_m::<OptionBrand, _, _>(|a| Some(ControlFlow::Break(a)), x) == Some(x)
1719 }
1720
1721 #[test]
1723 fn monad_rec_sum_range() {
1724 use {
1725 crate::classes::monad_rec::tail_rec_m,
1726 core::ops::ControlFlow,
1727 };
1728 let result = tail_rec_m::<OptionBrand, _, _>(
1730 |(n, acc)| {
1731 if n == 0 {
1732 Some(ControlFlow::Break(acc))
1733 } else {
1734 Some(ControlFlow::Continue((n - 1, acc + n)))
1735 }
1736 },
1737 (100i64, 0i64),
1738 );
1739 assert_eq!(result, Some(5050));
1740 }
1741
1742 #[test]
1744 fn monad_rec_short_circuit() {
1745 use {
1746 crate::classes::monad_rec::tail_rec_m,
1747 core::ops::ControlFlow,
1748 };
1749 let result: Option<i32> = tail_rec_m::<OptionBrand, _, _>(
1750 |n| {
1751 if n == 5 { None } else { Some(ControlFlow::Continue(n + 1)) }
1752 },
1753 0,
1754 );
1755 assert_eq!(result, None);
1756 }
1757
1758 #[test]
1760 fn monad_rec_stack_safety() {
1761 use {
1762 crate::classes::monad_rec::tail_rec_m,
1763 core::ops::ControlFlow,
1764 };
1765 let iterations: i64 = 200_000;
1766 let result = tail_rec_m::<OptionBrand, _, _>(
1767 |acc| {
1768 if acc < iterations {
1769 Some(ControlFlow::Continue(acc + 1))
1770 } else {
1771 Some(ControlFlow::Break(acc))
1772 }
1773 },
1774 0i64,
1775 );
1776 assert_eq!(result, Some(iterations));
1777 }
1778
1779 #[quickcheck]
1783 fn ref_functor_identity(opt: Option<i32>) -> bool {
1784 use crate::classes::ref_functor::RefFunctor;
1785 OptionBrand::ref_map(|x: &i32| *x, &opt) == opt
1786 }
1787
1788 #[quickcheck]
1790 fn ref_functor_composition(opt: Option<i32>) -> bool {
1791 use crate::classes::ref_functor::RefFunctor;
1792 let f = |x: &i32| x.wrapping_add(1);
1793 let g = |x: &i32| x.wrapping_mul(2);
1794 OptionBrand::ref_map(|x: &i32| f(&g(x)), &opt)
1795 == OptionBrand::ref_map(f, &OptionBrand::ref_map(g, &opt))
1796 }
1797
1798 #[quickcheck]
1802 fn ref_semimonad_left_identity(x: i32) -> bool {
1803 use crate::classes::ref_semimonad::RefSemimonad;
1804 OptionBrand::ref_bind(&Some(x), |a: &i32| Some(*a)) == Some(x)
1805 }
1806
1807 #[quickcheck]
1811 fn ref_foldable_fold_map(opt: Option<i32>) -> bool {
1812 use crate::{
1813 classes::ref_foldable::RefFoldable,
1814 types::Additive,
1815 };
1816 let result = OptionBrand::ref_fold_map::<RcFnBrand, _, _>(|x: &i32| Additive(*x), &opt);
1817 let expected = match opt {
1818 Some(v) => Additive(v),
1819 None => Additive(0),
1820 };
1821 result == expected
1822 }
1823
1824 #[quickcheck]
1829 fn ref_semimonad_right_identity(opt: Option<i32>) -> bool {
1830 use crate::classes::{
1831 ref_pointed::RefPointed,
1832 ref_semimonad::RefSemimonad,
1833 };
1834 OptionBrand::ref_bind(&opt, |a: &i32| OptionBrand::ref_pure(a)) == opt
1835 }
1836
1837 #[quickcheck]
1839 fn ref_semimonad_associativity(opt: Option<i32>) -> bool {
1840 use crate::classes::ref_semimonad::RefSemimonad;
1841 let f = |a: &i32| if *a > 0 { Some(a.wrapping_mul(2)) } else { None };
1842 let g = |b: &i32| Some(b.wrapping_add(10));
1843 let lhs = OptionBrand::ref_bind(&OptionBrand::ref_bind(&opt, f), g);
1844 let rhs = OptionBrand::ref_bind(&opt, |a: &i32| OptionBrand::ref_bind(&f(a), g));
1845 lhs == rhs
1846 }
1847
1848 #[quickcheck]
1853 fn ref_lift_identity(opt: Option<i32>) -> bool {
1854 use crate::classes::ref_lift::RefLift;
1855 OptionBrand::ref_lift2(|_: &(), b: &i32| *b, &Some(()), &opt) == opt
1856 }
1857
1858 #[quickcheck]
1861 fn ref_lift2_commutativity(
1862 a: Option<i32>,
1863 b: Option<i32>,
1864 ) -> bool {
1865 use crate::classes::ref_lift::RefLift;
1866 let lhs = OptionBrand::ref_lift2(|x: &i32, y: &i32| x.wrapping_add(*y), &a, &b);
1867 let rhs = OptionBrand::ref_lift2(|y: &i32, x: &i32| x.wrapping_add(*y), &b, &a);
1868 lhs == rhs
1869 }
1870
1871 #[quickcheck]
1876 fn ref_traversable_identity(opt: Option<i32>) -> bool {
1877 use crate::{
1878 classes::ref_traversable::RefTraversable,
1879 types::Identity,
1880 };
1881 let result: Identity<Option<i32>> =
1882 OptionBrand::ref_traverse::<RcFnBrand, _, _, IdentityBrand>(
1883 |a: &i32| Identity(*a),
1884 &opt,
1885 );
1886 result == Identity(opt)
1887 }
1888
1889 #[quickcheck]
1892 fn ref_traversable_consistent_with_traverse(opt: Option<i32>) -> bool {
1893 use crate::classes::{
1894 ref_traversable::RefTraversable,
1895 traversable::Traversable,
1896 };
1897 let ref_result: Option<Option<String>> =
1898 OptionBrand::ref_traverse::<RcFnBrand, _, _, OptionBrand>(
1899 |a: &i32| Some(a.to_string()),
1900 &opt,
1901 );
1902 let val_result: Option<Option<String>> =
1903 OptionBrand::traverse::<i32, String, OptionBrand>(|a: i32| Some(a.to_string()), opt);
1904 ref_result == val_result
1905 }
1906
1907 #[quickcheck]
1911 fn ref_compactable_identity(x: Option<i32>) -> bool {
1912 use crate::classes::ref_compactable::ref_compact;
1913 let mapped: Option<Option<i32>> = x.as_ref().map(|a| Some(*a));
1914 ref_compact::<OptionBrand, _>(&mapped) == x
1915 }
1916
1917 #[quickcheck]
1921 fn ref_alt_associativity(
1922 x: Option<i32>,
1923 y: Option<i32>,
1924 z: Option<i32>,
1925 ) -> bool {
1926 use crate::classes::ref_alt::ref_alt;
1927 ref_alt::<OptionBrand, _>(&ref_alt::<OptionBrand, _>(&x, &y), &z)
1928 == ref_alt::<OptionBrand, _>(&x, &ref_alt::<OptionBrand, _>(&y, &z))
1929 }
1930}