1#[fp_macros::document_module]
6mod inner {
7 use crate::{
8 Apply,
9 brands::Tuple1Brand,
10 classes::{
11 Applicative, ApplyFirst, ApplySecond, CloneableFn, Foldable, Functor, Lift, Monoid,
12 ParFoldable, Pointed, Semiapplicative, Semimonad, SendCloneableFn, Traversable,
13 },
14 impl_kind,
15 kinds::*,
16 };
17 use fp_macros::document_parameters;
18
19 impl_kind! {
20 for Tuple1Brand {
21 type Of<A> = (A,);
22 }
23 }
24
25 impl_kind! {
26 for Tuple1Brand {
27 type Of<'a, A: 'a>: 'a = (A,);
28 }
29 }
30
31 impl Functor for Tuple1Brand {
32 #[document_signature]
39 #[document_type_parameters(
43 "The lifetime of the value.",
44 "The type of the value inside the tuple.",
45 "The type of the result of applying the function.",
46 "The type of the function to apply."
47 )]
48 #[document_parameters("The function to apply.", "The tuple to map over.")]
52 fn map<'a, A: 'a, B: 'a, Func>(
67 func: Func,
68 fa: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
69 ) -> Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>)
70 where
71 Func: Fn(A) -> B + 'a,
72 {
73 (func(fa.0),)
74 }
75 }
76
77 impl Lift for Tuple1Brand {
78 #[document_signature]
85 #[document_type_parameters(
89 "The lifetime of the values.",
90 "The type of the first tuple's value.",
91 "The type of the second tuple's value.",
92 "The return type of the function.",
93 "The type of the binary function."
94 )]
95 #[document_parameters(
99 "The binary function to apply.",
100 "The first tuple.",
101 "The second tuple."
102 )]
103 fn lift2<'a, A, B, C, Func>(
119 func: Func,
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 Func: Fn(A, B) -> C + 'a,
125 A: 'a,
126 B: 'a,
127 C: 'a,
128 {
129 (func(fa.0, fb.0),)
130 }
131 }
132
133 impl Pointed for Tuple1Brand {
134 #[document_signature]
141 #[document_type_parameters("The lifetime of the value.", "The type of the value to wrap.")]
145 #[document_parameters("The value to wrap.")]
149 fn pure<'a, A: 'a>(a: A) -> Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>) {
163 (a,)
164 }
165 }
166
167 impl ApplyFirst for Tuple1Brand {}
168 impl ApplySecond for Tuple1Brand {}
169
170 impl Semiapplicative for Tuple1Brand {
171 #[document_signature]
178 #[document_type_parameters(
182 "The lifetime of the values.",
183 "The brand of the cloneable function wrapper.",
184 "The type of the input value.",
185 "The type of the output value."
186 )]
187 #[document_parameters(
191 "The tuple containing the function.",
192 "The tuple containing the value."
193 )]
194 fn apply<'a, FnBrand: 'a + CloneableFn, A: 'a + Clone, B: 'a>(
210 ff: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, <FnBrand as CloneableFn>::Of<'a, A, B>>),
211 fa: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
212 ) -> Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>) {
213 (ff.0(fa.0),)
214 }
215 }
216
217 impl Semimonad for Tuple1Brand {
218 #[document_signature]
225 #[document_type_parameters(
229 "The lifetime of the values.",
230 "The type of the result of the first computation.",
231 "The type of the result of the second computation.",
232 "The type of the function to apply."
233 )]
234 #[document_parameters(
238 "The first tuple.",
239 "The function to apply to the value inside the tuple."
240 )]
241 fn bind<'a, A: 'a, B: 'a, Func>(
256 ma: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
257 func: Func,
258 ) -> Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>)
259 where
260 Func: Fn(A) -> Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>) + 'a,
261 {
262 func(ma.0)
263 }
264 }
265
266 impl Foldable for Tuple1Brand {
267 #[document_signature]
274 #[document_type_parameters(
278 "The lifetime of the values.",
279 "The brand of the cloneable function to use.",
280 "The type of the elements in the structure.",
281 "The type of the accumulator.",
282 "The type of the folding function."
283 )]
284 #[document_parameters(
288 "The function to apply to each element and the accumulator.",
289 "The initial value of the accumulator.",
290 "The tuple to fold."
291 )]
292 fn fold_right<'a, FnBrand, A: 'a, B: 'a, Func>(
307 func: Func,
308 initial: B,
309 fa: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
310 ) -> B
311 where
312 Func: Fn(A, B) -> B + 'a,
313 FnBrand: CloneableFn + 'a,
314 {
315 func(fa.0, initial)
316 }
317
318 #[document_signature]
325 #[document_type_parameters(
329 "The lifetime of the values.",
330 "The brand of the cloneable function to use.",
331 "The type of the elements in the structure.",
332 "The type of the accumulator.",
333 "The type of the folding function."
334 )]
335 #[document_parameters(
339 "The function to apply to the accumulator and each element.",
340 "The initial value of the accumulator.",
341 "The tuple to fold."
342 )]
343 fn fold_left<'a, FnBrand, A: 'a, B: 'a, Func>(
358 func: Func,
359 initial: B,
360 fa: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
361 ) -> B
362 where
363 Func: Fn(B, A) -> B + 'a,
364 FnBrand: CloneableFn + 'a,
365 {
366 func(initial, fa.0)
367 }
368
369 #[document_signature]
376 #[document_type_parameters(
380 "The lifetime of the values.",
381 "The brand of the cloneable function to use.",
382 "The type of the elements in the structure.",
383 "The type of the monoid.",
384 "The type of the mapping function."
385 )]
386 #[document_parameters(
390 "The thread-safe function to map each element to a monoid.",
391 "The tuple to fold."
392 )]
393 fn fold_map<'a, FnBrand, A: 'a, M, Func>(
408 func: Func,
409 fa: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
410 ) -> M
411 where
412 M: Monoid + 'a,
413 Func: Fn(A) -> M + 'a,
414 FnBrand: CloneableFn + 'a,
415 {
416 func(fa.0)
417 }
418 }
419
420 impl Traversable for Tuple1Brand {
421 #[document_signature]
428 #[document_type_parameters(
432 "The lifetime of the values.",
433 "The type of the elements in the traversable structure.",
434 "The type of the elements in the resulting traversable structure.",
435 "The applicative context.",
436 "The type of the function to apply."
437 )]
438 #[document_parameters(
442 "The function to apply to each element, returning a value in an applicative context.",
443 "The tuple to traverse."
444 )]
445 fn traverse<'a, A: 'a + Clone, B: 'a + Clone, F: Applicative, Func>(
460 func: Func,
461 ta: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
462 ) -> 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>)>)
463 where
464 Func: Fn(A) -> Apply!(<F as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>) + 'a,
465 Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>): Clone,
466 {
467 F::map(|b| (b,), func(ta.0))
468 }
469
470 #[document_signature]
477 #[document_type_parameters(
481 "The lifetime of the values.",
482 "The type of the elements in the traversable structure.",
483 "The applicative context."
484 )]
485 #[document_parameters("The tuple containing the applicative value.")]
489 fn sequence<'a, A: 'a + Clone, F: Applicative>(
504 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>)>)
505 ) -> 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>)>)
506 where
507 Apply!(<F as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>): Clone,
508 Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>): Clone,
509 {
510 F::map(|a| (a,), ta.0)
511 }
512 }
513
514 impl ParFoldable for Tuple1Brand {
515 #[document_signature]
522 #[document_type_parameters(
526 "The lifetime of the values.",
527 "The brand of the cloneable function wrapper.",
528 "The element type.",
529 "The monoid type."
530 )]
531 #[document_parameters(
535 "The function to map each element to a monoid.",
536 "The tuple to fold."
537 )]
538 fn par_fold_map<'a, FnBrand, A, M>(
554 func: <FnBrand as SendCloneableFn>::SendOf<'a, A, M>,
555 fa: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
556 ) -> M
557 where
558 FnBrand: 'a + SendCloneableFn,
559 A: 'a + Clone + Send + Sync,
560 M: Monoid + Send + Sync + 'a,
561 {
562 func(fa.0)
563 }
564
565 #[document_signature]
572 #[document_type_parameters(
576 "The lifetime of the values.",
577 "The brand of the cloneable function wrapper.",
578 "The element type.",
579 "The accumulator type."
580 )]
581 #[document_parameters(
585 "The thread-safe function to apply to each element and the accumulator.",
586 "The initial value of the accumulator.",
587 "The tuple to fold."
588 )]
589 fn par_fold_right<'a, FnBrand, A, B>(
605 func: <FnBrand as SendCloneableFn>::SendOf<'a, (A, B), B>,
606 initial: B,
607 fa: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
608 ) -> B
609 where
610 FnBrand: 'a + SendCloneableFn,
611 A: 'a + Clone + Send + Sync,
612 B: Send + Sync + 'a,
613 {
614 func((fa.0, initial))
615 }
616 }
617}
618
619#[cfg(test)]
620mod tests {
621
622 use crate::{
623 brands::{OptionBrand, RcFnBrand, Tuple1Brand},
624 classes::{
625 CloneableFn, functor::map, pointed::pure, semiapplicative::apply, semimonad::bind,
626 },
627 functions::{compose, identity},
628 };
629 use quickcheck_macros::quickcheck;
630
631 #[quickcheck]
635 fn functor_identity(x: i32) -> bool {
636 let x = (x,);
637 map::<Tuple1Brand, _, _, _>(identity, x) == x
638 }
639
640 #[quickcheck]
642 fn functor_composition(x: i32) -> bool {
643 let x = (x,);
644 let f = |x: i32| x.wrapping_add(1);
645 let g = |x: i32| x.wrapping_mul(2);
646 map::<Tuple1Brand, _, _, _>(compose(f, g), x)
647 == map::<Tuple1Brand, _, _, _>(f, map::<Tuple1Brand, _, _, _>(g, x))
648 }
649
650 #[quickcheck]
654 fn applicative_identity(v: i32) -> bool {
655 let v = (v,);
656 apply::<RcFnBrand, Tuple1Brand, _, _>(
657 pure::<Tuple1Brand, _>(<RcFnBrand as CloneableFn>::new(identity)),
658 v,
659 ) == v
660 }
661
662 #[quickcheck]
664 fn applicative_homomorphism(x: i32) -> bool {
665 let f = |x: i32| x.wrapping_mul(2);
666 apply::<RcFnBrand, Tuple1Brand, _, _>(
667 pure::<Tuple1Brand, _>(<RcFnBrand as CloneableFn>::new(f)),
668 pure::<Tuple1Brand, _>(x),
669 ) == pure::<Tuple1Brand, _>(f(x))
670 }
671
672 #[quickcheck]
674 fn applicative_composition(
675 w: i32,
676 u_val: i32,
677 v_val: i32,
678 ) -> bool {
679 let w = (w,);
680 let v_fn = move |x: i32| x.wrapping_mul(v_val);
681 let u_fn = move |x: i32| x.wrapping_add(u_val);
682
683 let v = pure::<Tuple1Brand, _>(<RcFnBrand as CloneableFn>::new(v_fn));
684 let u = pure::<Tuple1Brand, _>(<RcFnBrand as CloneableFn>::new(u_fn));
685
686 let vw = apply::<RcFnBrand, Tuple1Brand, _, _>(v.clone(), w.clone());
688 let rhs = apply::<RcFnBrand, Tuple1Brand, _, _>(u.clone(), vw);
689
690 let composed = move |x| u_fn(v_fn(x));
692 let uv = pure::<Tuple1Brand, _>(<RcFnBrand as CloneableFn>::new(composed));
693
694 let lhs = apply::<RcFnBrand, Tuple1Brand, _, _>(uv, w);
695
696 lhs == rhs
697 }
698
699 #[quickcheck]
701 fn applicative_interchange(y: i32) -> bool {
702 let f = |x: i32| x.wrapping_mul(2);
704 let u = pure::<Tuple1Brand, _>(<RcFnBrand as CloneableFn>::new(f));
705
706 let lhs = apply::<RcFnBrand, Tuple1Brand, _, _>(u.clone(), pure::<Tuple1Brand, _>(y));
707
708 let rhs_fn =
709 <RcFnBrand as CloneableFn>::new(move |f: std::rc::Rc<dyn Fn(i32) -> i32>| f(y));
710 let rhs = apply::<RcFnBrand, Tuple1Brand, _, _>(pure::<Tuple1Brand, _>(rhs_fn), u);
711
712 lhs == rhs
713 }
714
715 #[quickcheck]
719 fn monad_left_identity(a: i32) -> bool {
720 let f = |x: i32| (x.wrapping_mul(2),);
721 bind::<Tuple1Brand, _, _, _>(pure::<Tuple1Brand, _>(a), f) == f(a)
722 }
723
724 #[quickcheck]
726 fn monad_right_identity(m: i32) -> bool {
727 let m = (m,);
728 bind::<Tuple1Brand, _, _, _>(m, pure::<Tuple1Brand, _>) == m
729 }
730
731 #[quickcheck]
733 fn monad_associativity(m: i32) -> bool {
734 let m = (m,);
735 let f = |x: i32| (x.wrapping_mul(2),);
736 let g = |x: i32| (x.wrapping_add(1),);
737 bind::<Tuple1Brand, _, _, _>(bind::<Tuple1Brand, _, _, _>(m, f), g)
738 == bind::<Tuple1Brand, _, _, _>(m, |x| bind::<Tuple1Brand, _, _, _>(f(x), g))
739 }
740
741 #[test]
745 fn map_test() {
746 assert_eq!(map::<Tuple1Brand, _, _, _>(|x: i32| x + 1, (1,)), (2,));
747 }
748
749 #[test]
751 fn bind_test() {
752 assert_eq!(bind::<Tuple1Brand, _, _, _>((1,), |x| (x + 1,)), (2,));
753 }
754
755 #[test]
757 fn fold_right_test() {
758 assert_eq!(
759 crate::classes::foldable::fold_right::<RcFnBrand, Tuple1Brand, _, _, _>(
760 |x: i32, acc| x + acc,
761 0,
762 (1,)
763 ),
764 1
765 );
766 }
767
768 #[test]
770 fn fold_left_test() {
771 assert_eq!(
772 crate::classes::foldable::fold_left::<RcFnBrand, Tuple1Brand, _, _, _>(
773 |acc, x: i32| acc + x,
774 0,
775 (1,)
776 ),
777 1
778 );
779 }
780
781 #[test]
783 fn traverse_test() {
784 assert_eq!(
785 crate::classes::traversable::traverse::<Tuple1Brand, _, _, OptionBrand, _>(
786 |x: i32| Some(x + 1),
787 (1,)
788 ),
789 Some((2,))
790 );
791 }
792
793 #[test]
797 fn par_fold_map_test() {
798 use crate::{brands::*, functions::*};
799
800 let x = (1,);
801 let f = send_cloneable_fn_new::<ArcFnBrand, _, _>(|x: i32| x.to_string());
802 assert_eq!(par_fold_map::<ArcFnBrand, Tuple1Brand, _, _>(f, x), "1".to_string());
803 }
804
805 #[test]
807 fn par_fold_right_test() {
808 use crate::{brands::*, functions::*};
809
810 let x = (1,);
811 let f = send_cloneable_fn_new::<ArcFnBrand, _, _>(|(a, b): (i32, i32)| a + b);
812 assert_eq!(par_fold_right::<ArcFnBrand, Tuple1Brand, _, _>(f, 10, x), 11);
813 }
814}