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(pure::<OptionBrand, _>(<RcFnBrand as LiftFn>::new(identity)), v) == v
1547 }
1548
1549 #[quickcheck]
1551 fn applicative_homomorphism(x: i32) -> bool {
1552 let f = |x: i32| x.wrapping_mul(2);
1553 apply(pure::<OptionBrand, _>(<RcFnBrand as LiftFn>::new(f)), pure::<OptionBrand, _>(x))
1554 == pure::<OptionBrand, _>(f(x))
1555 }
1556
1557 #[quickcheck]
1559 fn applicative_composition(
1560 w: Option<i32>,
1561 u_is_some: bool,
1562 v_is_some: bool,
1563 ) -> bool {
1564 let v_fn = |x: i32| x.wrapping_mul(2);
1565 let u_fn = |x: i32| x.wrapping_add(1);
1566
1567 let v =
1568 if v_is_some { pure::<OptionBrand, _>(<RcFnBrand as LiftFn>::new(v_fn)) } else { None };
1569 let u =
1570 if u_is_some { pure::<OptionBrand, _>(<RcFnBrand as LiftFn>::new(u_fn)) } else { None };
1571
1572 let vw = apply(v.clone(), w);
1574 let rhs = apply(u.clone(), vw);
1575
1576 let uv = match (u, v) {
1579 (Some(uf), Some(vf)) => {
1580 let composed = move |x| uf(vf(x));
1581 Some(<RcFnBrand as LiftFn>::new(composed))
1582 }
1583 _ => None,
1584 };
1585
1586 let lhs = apply(uv, w);
1587
1588 lhs == rhs
1589 }
1590
1591 #[quickcheck]
1593 fn applicative_interchange(y: i32) -> bool {
1594 let f = |x: i32| x.wrapping_mul(2);
1596 let u = pure::<OptionBrand, _>(<RcFnBrand as LiftFn>::new(f));
1597
1598 let lhs = apply(u.clone(), pure::<OptionBrand, _>(y));
1599
1600 let rhs_fn = <RcFnBrand as LiftFn>::new(move |f: std::rc::Rc<dyn Fn(i32) -> i32>| f(y));
1601 let rhs = apply(pure::<OptionBrand, _>(rhs_fn), u);
1602
1603 lhs == rhs
1604 }
1605
1606 #[quickcheck]
1610 fn monad_left_identity(a: i32) -> bool {
1611 let f = |x: i32| Some(x.wrapping_mul(2));
1612 explicit::bind::<OptionBrand, _, _, _, _>(pure::<OptionBrand, _>(a), f) == f(a)
1613 }
1614
1615 #[quickcheck]
1617 fn monad_right_identity(m: Option<i32>) -> bool {
1618 explicit::bind::<OptionBrand, _, _, _, _>(m, pure::<OptionBrand, _>) == m
1619 }
1620
1621 #[quickcheck]
1623 fn monad_associativity(m: Option<i32>) -> bool {
1624 let f = |x: i32| Some(x.wrapping_mul(2));
1625 let g = |x: i32| Some(x.wrapping_add(1));
1626 explicit::bind::<OptionBrand, _, _, _, _>(
1627 explicit::bind::<OptionBrand, _, _, _, _>(m, f),
1628 g,
1629 ) == explicit::bind::<OptionBrand, _, _, _, _>(m, |x| {
1630 explicit::bind::<OptionBrand, _, _, _, _>(f(x), g)
1631 })
1632 }
1633
1634 #[test]
1638 fn map_none() {
1639 assert_eq!(explicit::map::<OptionBrand, _, _, _, _>(|x: i32| x + 1, None), None);
1640 }
1641
1642 #[test]
1644 fn bind_none() {
1645 assert_eq!(explicit::bind::<OptionBrand, _, _, _, _>(None, |x: i32| Some(x + 1)), None);
1646 }
1647
1648 #[test]
1650 fn bind_returning_none() {
1651 assert_eq!(explicit::bind::<OptionBrand, _, _, _, _>(Some(5), |_| None::<i32>), None);
1652 }
1653
1654 #[test]
1656 fn fold_right_none() {
1657 assert_eq!(
1658 crate::functions::explicit::fold_right::<RcFnBrand, OptionBrand, _, _, _, _>(
1659 |x: i32, acc| x + acc,
1660 0,
1661 None
1662 ),
1663 0
1664 );
1665 }
1666
1667 #[test]
1669 fn fold_left_none() {
1670 assert_eq!(
1671 crate::functions::explicit::fold_left::<RcFnBrand, OptionBrand, _, _, _, _>(
1672 |acc, x: i32| acc + x,
1673 0,
1674 None
1675 ),
1676 0
1677 );
1678 }
1679
1680 #[test]
1682 fn traverse_none() {
1683 assert_eq!(
1684 crate::classes::traversable::traverse::<OptionBrand, _, _, OptionBrand>(
1685 |x: i32| Some(x + 1),
1686 None
1687 ),
1688 Some(None)
1689 );
1690 }
1691
1692 #[test]
1694 fn traverse_returning_none() {
1695 assert_eq!(
1696 crate::classes::traversable::traverse::<OptionBrand, _, _, OptionBrand>(
1697 |_: i32| None::<i32>,
1698 Some(5)
1699 ),
1700 None
1701 );
1702 }
1703
1704 #[quickcheck]
1708 fn monad_rec_identity(x: i32) -> bool {
1709 use {
1710 crate::classes::monad_rec::tail_rec_m,
1711 core::ops::ControlFlow,
1712 };
1713 tail_rec_m::<OptionBrand, _, _>(|a| Some(ControlFlow::Break(a)), x) == Some(x)
1714 }
1715
1716 #[test]
1718 fn monad_rec_sum_range() {
1719 use {
1720 crate::classes::monad_rec::tail_rec_m,
1721 core::ops::ControlFlow,
1722 };
1723 let result = tail_rec_m::<OptionBrand, _, _>(
1725 |(n, acc)| {
1726 if n == 0 {
1727 Some(ControlFlow::Break(acc))
1728 } else {
1729 Some(ControlFlow::Continue((n - 1, acc + n)))
1730 }
1731 },
1732 (100i64, 0i64),
1733 );
1734 assert_eq!(result, Some(5050));
1735 }
1736
1737 #[test]
1739 fn monad_rec_short_circuit() {
1740 use {
1741 crate::classes::monad_rec::tail_rec_m,
1742 core::ops::ControlFlow,
1743 };
1744 let result: Option<i32> = tail_rec_m::<OptionBrand, _, _>(
1745 |n| {
1746 if n == 5 { None } else { Some(ControlFlow::Continue(n + 1)) }
1747 },
1748 0,
1749 );
1750 assert_eq!(result, None);
1751 }
1752
1753 #[test]
1755 fn monad_rec_stack_safety() {
1756 use {
1757 crate::classes::monad_rec::tail_rec_m,
1758 core::ops::ControlFlow,
1759 };
1760 let iterations: i64 = 200_000;
1761 let result = tail_rec_m::<OptionBrand, _, _>(
1762 |acc| {
1763 if acc < iterations {
1764 Some(ControlFlow::Continue(acc + 1))
1765 } else {
1766 Some(ControlFlow::Break(acc))
1767 }
1768 },
1769 0i64,
1770 );
1771 assert_eq!(result, Some(iterations));
1772 }
1773
1774 #[quickcheck]
1778 fn ref_functor_identity(opt: Option<i32>) -> bool {
1779 use crate::classes::ref_functor::RefFunctor;
1780 OptionBrand::ref_map(|x: &i32| *x, &opt) == opt
1781 }
1782
1783 #[quickcheck]
1785 fn ref_functor_composition(opt: Option<i32>) -> bool {
1786 use crate::classes::ref_functor::RefFunctor;
1787 let f = |x: &i32| x.wrapping_add(1);
1788 let g = |x: &i32| x.wrapping_mul(2);
1789 OptionBrand::ref_map(|x: &i32| f(&g(x)), &opt)
1790 == OptionBrand::ref_map(f, &OptionBrand::ref_map(g, &opt))
1791 }
1792
1793 #[quickcheck]
1797 fn ref_semimonad_left_identity(x: i32) -> bool {
1798 use crate::classes::ref_semimonad::RefSemimonad;
1799 OptionBrand::ref_bind(&Some(x), |a: &i32| Some(*a)) == Some(x)
1800 }
1801
1802 #[quickcheck]
1806 fn ref_foldable_fold_map(opt: Option<i32>) -> bool {
1807 use crate::{
1808 classes::ref_foldable::RefFoldable,
1809 types::Additive,
1810 };
1811 let result = OptionBrand::ref_fold_map::<RcFnBrand, _, _>(|x: &i32| Additive(*x), &opt);
1812 let expected = match opt {
1813 Some(v) => Additive(v),
1814 None => Additive(0),
1815 };
1816 result == expected
1817 }
1818
1819 #[quickcheck]
1824 fn ref_semimonad_right_identity(opt: Option<i32>) -> bool {
1825 use crate::classes::{
1826 ref_pointed::RefPointed,
1827 ref_semimonad::RefSemimonad,
1828 };
1829 OptionBrand::ref_bind(&opt, |a: &i32| OptionBrand::ref_pure(a)) == opt
1830 }
1831
1832 #[quickcheck]
1834 fn ref_semimonad_associativity(opt: Option<i32>) -> bool {
1835 use crate::classes::ref_semimonad::RefSemimonad;
1836 let f = |a: &i32| if *a > 0 { Some(a.wrapping_mul(2)) } else { None };
1837 let g = |b: &i32| Some(b.wrapping_add(10));
1838 let lhs = OptionBrand::ref_bind(&OptionBrand::ref_bind(&opt, f), g);
1839 let rhs = OptionBrand::ref_bind(&opt, |a: &i32| OptionBrand::ref_bind(&f(a), g));
1840 lhs == rhs
1841 }
1842
1843 #[quickcheck]
1848 fn ref_lift_identity(opt: Option<i32>) -> bool {
1849 use crate::classes::ref_lift::RefLift;
1850 OptionBrand::ref_lift2(|_: &(), b: &i32| *b, &Some(()), &opt) == opt
1851 }
1852
1853 #[quickcheck]
1856 fn ref_lift2_commutativity(
1857 a: Option<i32>,
1858 b: Option<i32>,
1859 ) -> bool {
1860 use crate::classes::ref_lift::RefLift;
1861 let lhs = OptionBrand::ref_lift2(|x: &i32, y: &i32| x.wrapping_add(*y), &a, &b);
1862 let rhs = OptionBrand::ref_lift2(|y: &i32, x: &i32| x.wrapping_add(*y), &b, &a);
1863 lhs == rhs
1864 }
1865
1866 #[quickcheck]
1871 fn ref_traversable_identity(opt: Option<i32>) -> bool {
1872 use crate::{
1873 classes::ref_traversable::RefTraversable,
1874 types::Identity,
1875 };
1876 let result: Identity<Option<i32>> =
1877 OptionBrand::ref_traverse::<RcFnBrand, _, _, IdentityBrand>(
1878 |a: &i32| Identity(*a),
1879 &opt,
1880 );
1881 result == Identity(opt)
1882 }
1883
1884 #[quickcheck]
1887 fn ref_traversable_consistent_with_traverse(opt: Option<i32>) -> bool {
1888 use crate::classes::{
1889 ref_traversable::RefTraversable,
1890 traversable::Traversable,
1891 };
1892 let ref_result: Option<Option<String>> =
1893 OptionBrand::ref_traverse::<RcFnBrand, _, _, OptionBrand>(
1894 |a: &i32| Some(a.to_string()),
1895 &opt,
1896 );
1897 let val_result: Option<Option<String>> =
1898 OptionBrand::traverse::<i32, String, OptionBrand>(|a: i32| Some(a.to_string()), opt);
1899 ref_result == val_result
1900 }
1901
1902 #[quickcheck]
1906 fn ref_compactable_identity(x: Option<i32>) -> bool {
1907 use crate::classes::ref_compactable::ref_compact;
1908 let mapped: Option<Option<i32>> = x.as_ref().map(|a| Some(*a));
1909 ref_compact::<OptionBrand, _>(&mapped) == x
1910 }
1911
1912 #[quickcheck]
1916 fn ref_alt_associativity(
1917 x: Option<i32>,
1918 y: Option<i32>,
1919 z: Option<i32>,
1920 ) -> bool {
1921 use crate::classes::ref_alt::ref_alt;
1922 ref_alt::<OptionBrand, _>(&ref_alt::<OptionBrand, _>(&x, &y), &z)
1923 == ref_alt::<OptionBrand, _>(&x, &ref_alt::<OptionBrand, _>(&y, &z))
1924 }
1925}