1#[fp_macros::document_module]
6mod inner {
7 use {
8 crate::{
9 Apply,
10 brands::Tuple1Brand,
11 classes::{
12 Applicative,
13 ApplyFirst,
14 ApplySecond,
15 CloneableFn,
16 Foldable,
17 Functor,
18 Lift,
19 Monoid,
20 ParFoldable,
21 Pointed,
22 Semiapplicative,
23 Semimonad,
24 SendCloneableFn,
25 Traversable,
26 },
27 impl_kind,
28 kinds::*,
29 },
30 fp_macros::*,
31 };
32
33 impl_kind! {
34 for Tuple1Brand {
35 type Of<A> = (A,);
36 }
37 }
38
39 impl_kind! {
40 for Tuple1Brand {
41 type Of<'a, A: 'a>: 'a = (A,);
42 }
43 }
44
45 impl Functor for Tuple1Brand {
46 #[document_signature]
50 #[document_type_parameters(
52 "The lifetime of the value.",
53 "The type of the value inside the tuple.",
54 "The type of the result of applying the function."
55 )]
56 #[document_parameters("The function to apply.", "The tuple to map over.")]
58 #[document_returns("A new 1-tuple containing the result of applying the function.")]
60 #[document_examples]
62 fn map<'a, A: 'a, B: 'a>(
74 func: impl Fn(A) -> B + 'a,
75 fa: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
76 ) -> Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>) {
77 (func(fa.0),)
78 }
79 }
80
81 impl Lift for Tuple1Brand {
82 #[document_signature]
86 #[document_type_parameters(
88 "The lifetime of the values.",
89 "The type of the first tuple's value.",
90 "The type of the second tuple's value.",
91 "The return type of the function."
92 )]
93 #[document_parameters(
95 "The binary function to apply.",
96 "The first tuple.",
97 "The second tuple."
98 )]
99 #[document_returns("A new 1-tuple containing the result of applying the function.")]
101 #[document_examples]
102 fn lift2<'a, A, B, C>(
115 func: impl Fn(A, B) -> C + 'a,
116 fa: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
117 fb: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>),
118 ) -> Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, C>)
119 where
120 A: 'a,
121 B: 'a,
122 C: 'a, {
123 (func(fa.0, fb.0),)
124 }
125 }
126
127 impl Pointed for Tuple1Brand {
128 #[document_signature]
132 #[document_type_parameters("The lifetime of the value.", "The type of the value to wrap.")]
134 #[document_parameters("The value to wrap.")]
136 #[document_returns("A 1-tuple containing the value.")]
138 #[document_examples]
140 fn pure<'a, A: 'a>(a: A) -> Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>) {
151 (a,)
152 }
153 }
154
155 impl ApplyFirst for Tuple1Brand {}
156 impl ApplySecond for Tuple1Brand {}
157
158 impl Semiapplicative for Tuple1Brand {
159 #[document_signature]
163 #[document_type_parameters(
165 "The lifetime of the values.",
166 "The brand of the cloneable function wrapper.",
167 "The type of the input value.",
168 "The type of the output value."
169 )]
170 #[document_parameters(
172 "The tuple containing the function.",
173 "The tuple containing the value."
174 )]
175 #[document_returns("A new 1-tuple containing the result of applying the function.")]
177 #[document_examples]
178 fn apply<'a, FnBrand: 'a + CloneableFn, A: 'a + Clone, B: 'a>(
191 ff: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, <FnBrand as CloneableFn>::Of<'a, A, B>>),
192 fa: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
193 ) -> Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>) {
194 (ff.0(fa.0),)
195 }
196 }
197
198 impl Semimonad for Tuple1Brand {
199 #[document_signature]
203 #[document_type_parameters(
205 "The lifetime of the values.",
206 "The type of the result of the first computation.",
207 "The type of the result of the second computation."
208 )]
209 #[document_parameters(
211 "The first tuple.",
212 "The function to apply to the value inside the tuple."
213 )]
214 #[document_returns("The result of applying `f` to the value.")]
216 #[document_examples]
217 fn bind<'a, A: 'a, B: 'a>(
229 ma: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
230 func: impl Fn(A) -> Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>) + 'a,
231 ) -> Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>) {
232 func(ma.0)
233 }
234 }
235
236 impl Foldable for Tuple1Brand {
237 #[document_signature]
241 #[document_type_parameters(
243 "The lifetime of the values.",
244 "The brand of the cloneable function to use.",
245 "The type of the elements in the structure.",
246 "The type of the accumulator."
247 )]
248 #[document_parameters(
250 "The function to apply to each element and the accumulator.",
251 "The initial value of the accumulator.",
252 "The tuple to fold."
253 )]
254 #[document_returns("The final accumulator value.")]
256 #[document_examples]
257 fn fold_right<'a, FnBrand, A: 'a + Clone, B: 'a>(
269 func: impl Fn(A, B) -> B + 'a,
270 initial: B,
271 fa: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
272 ) -> B
273 where
274 FnBrand: CloneableFn + 'a, {
275 func(fa.0, initial)
276 }
277
278 #[document_signature]
282 #[document_type_parameters(
284 "The lifetime of the values.",
285 "The brand of the cloneable function to use.",
286 "The type of the elements in the structure.",
287 "The type of the accumulator."
288 )]
289 #[document_parameters(
291 "The function to apply to the accumulator and each element.",
292 "The initial value of the accumulator.",
293 "The tuple to fold."
294 )]
295 #[document_returns("The final accumulator value.")]
297 #[document_examples]
298 fn fold_left<'a, FnBrand, A: 'a + Clone, B: 'a>(
310 func: impl Fn(B, A) -> B + 'a,
311 initial: B,
312 fa: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
313 ) -> B
314 where
315 FnBrand: CloneableFn + 'a, {
316 func(initial, fa.0)
317 }
318
319 #[document_signature]
323 #[document_type_parameters(
325 "The lifetime of the values.",
326 "The brand of the cloneable function to use.",
327 "The type of the elements in the structure.",
328 "The type of the monoid."
329 )]
330 #[document_parameters(
332 "The thread-safe function to map each element to a monoid.",
333 "The tuple to fold."
334 )]
335 #[document_returns("The monoid value.")]
337 #[document_examples]
338 fn fold_map<'a, FnBrand, A: 'a + Clone, M>(
350 func: impl Fn(A) -> M + 'a,
351 fa: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
352 ) -> M
353 where
354 M: Monoid + 'a,
355 FnBrand: CloneableFn + 'a, {
356 func(fa.0)
357 }
358 }
359
360 impl Traversable for Tuple1Brand {
361 #[document_signature]
365 #[document_type_parameters(
367 "The lifetime of the values.",
368 "The type of the elements in the traversable structure.",
369 "The type of the elements in the resulting traversable structure.",
370 "The applicative context."
371 )]
372 #[document_parameters(
374 "The function to apply to each element, returning a value in an applicative context.",
375 "The tuple to traverse."
376 )]
377 #[document_returns("The 1-tuple wrapped in the applicative context.")]
379 #[document_examples]
380 fn traverse<'a, A: 'a + Clone, B: 'a + Clone, F: Applicative>(
392 func: impl Fn(A) -> Apply!(<F as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>) + 'a,
393 ta: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
394 ) -> 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>)>)
395 where
396 Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>): Clone, {
397 F::map(|b| (b,), func(ta.0))
398 }
399
400 #[document_signature]
404 #[document_type_parameters(
406 "The lifetime of the values.",
407 "The type of the elements in the traversable structure.",
408 "The applicative context."
409 )]
410 #[document_parameters("The tuple containing the applicative value.")]
412 #[document_returns("The 1-tuple wrapped in the applicative context.")]
414 #[document_examples]
416 fn sequence<'a, A: 'a + Clone, F: Applicative>(
428 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>)>)
429 ) -> 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>)>)
430 where
431 Apply!(<F as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>): Clone,
432 Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>): Clone, {
433 F::map(|a| (a,), ta.0)
434 }
435 }
436
437 impl ParFoldable for Tuple1Brand {
438 #[document_signature]
442 #[document_type_parameters(
444 "The lifetime of the values.",
445 "The brand of the cloneable function wrapper.",
446 "The element type.",
447 "The monoid type."
448 )]
449 #[document_parameters(
451 "The function to map each element to a monoid.",
452 "The tuple to fold."
453 )]
454 #[document_returns("The combined monoid value.")]
456 #[document_examples]
457 fn par_fold_map<'a, FnBrand, A, M>(
470 func: <FnBrand as SendCloneableFn>::SendOf<'a, A, M>,
471 fa: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
472 ) -> M
473 where
474 FnBrand: 'a + SendCloneableFn,
475 A: 'a + Clone + Send + Sync,
476 M: Monoid + Send + Sync + 'a, {
477 func(fa.0)
478 }
479
480 #[document_signature]
484 #[document_type_parameters(
486 "The lifetime of the values.",
487 "The brand of the cloneable function wrapper.",
488 "The element type.",
489 "The accumulator type."
490 )]
491 #[document_parameters(
493 "The thread-safe function to apply to each element and the accumulator.",
494 "The initial value of the accumulator.",
495 "The tuple to fold."
496 )]
497 #[document_returns("The final accumulator value.")]
499 #[document_examples]
500 fn par_fold_right<'a, FnBrand, A, B>(
513 func: <FnBrand as SendCloneableFn>::SendOf<'a, (A, B), B>,
514 initial: B,
515 fa: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
516 ) -> B
517 where
518 FnBrand: 'a + SendCloneableFn,
519 A: 'a + Clone + Send + Sync,
520 B: Send + Sync + 'a, {
521 func((fa.0, initial))
522 }
523 }
524}
525
526#[cfg(test)]
527mod tests {
528
529 use {
530 crate::{
531 brands::{
532 OptionBrand,
533 RcFnBrand,
534 Tuple1Brand,
535 },
536 classes::{
537 CloneableFn,
538 functor::map,
539 pointed::pure,
540 semiapplicative::apply,
541 semimonad::bind,
542 },
543 functions::{
544 compose,
545 identity,
546 },
547 },
548 quickcheck_macros::quickcheck,
549 };
550
551 #[quickcheck]
555 fn functor_identity(x: i32) -> bool {
556 let x = (x,);
557 map::<Tuple1Brand, _, _>(identity, x) == x
558 }
559
560 #[quickcheck]
562 fn functor_composition(x: i32) -> bool {
563 let x = (x,);
564 let f = |x: i32| x.wrapping_add(1);
565 let g = |x: i32| x.wrapping_mul(2);
566 map::<Tuple1Brand, _, _>(compose(f, g), x)
567 == map::<Tuple1Brand, _, _>(f, map::<Tuple1Brand, _, _>(g, x))
568 }
569
570 #[quickcheck]
574 fn applicative_identity(v: i32) -> bool {
575 let v = (v,);
576 apply::<RcFnBrand, Tuple1Brand, _, _>(
577 pure::<Tuple1Brand, _>(<RcFnBrand as CloneableFn>::new(identity)),
578 v,
579 ) == v
580 }
581
582 #[quickcheck]
584 fn applicative_homomorphism(x: i32) -> bool {
585 let f = |x: i32| x.wrapping_mul(2);
586 apply::<RcFnBrand, Tuple1Brand, _, _>(
587 pure::<Tuple1Brand, _>(<RcFnBrand as CloneableFn>::new(f)),
588 pure::<Tuple1Brand, _>(x),
589 ) == pure::<Tuple1Brand, _>(f(x))
590 }
591
592 #[quickcheck]
594 fn applicative_composition(
595 w: i32,
596 u_val: i32,
597 v_val: i32,
598 ) -> bool {
599 let w = (w,);
600 let v_fn = move |x: i32| x.wrapping_mul(v_val);
601 let u_fn = move |x: i32| x.wrapping_add(u_val);
602
603 let v = pure::<Tuple1Brand, _>(<RcFnBrand as CloneableFn>::new(v_fn));
604 let u = pure::<Tuple1Brand, _>(<RcFnBrand as CloneableFn>::new(u_fn));
605
606 let vw = apply::<RcFnBrand, Tuple1Brand, _, _>(v.clone(), w);
608 let rhs = apply::<RcFnBrand, Tuple1Brand, _, _>(u.clone(), vw);
609
610 let composed = move |x| u_fn(v_fn(x));
612 let uv = pure::<Tuple1Brand, _>(<RcFnBrand as CloneableFn>::new(composed));
613
614 let lhs = apply::<RcFnBrand, Tuple1Brand, _, _>(uv, w);
615
616 lhs == rhs
617 }
618
619 #[quickcheck]
621 fn applicative_interchange(y: i32) -> bool {
622 let f = |x: i32| x.wrapping_mul(2);
624 let u = pure::<Tuple1Brand, _>(<RcFnBrand as CloneableFn>::new(f));
625
626 let lhs = apply::<RcFnBrand, Tuple1Brand, _, _>(u.clone(), pure::<Tuple1Brand, _>(y));
627
628 let rhs_fn =
629 <RcFnBrand as CloneableFn>::new(move |f: std::rc::Rc<dyn Fn(i32) -> i32>| f(y));
630 let rhs = apply::<RcFnBrand, Tuple1Brand, _, _>(pure::<Tuple1Brand, _>(rhs_fn), u);
631
632 lhs == rhs
633 }
634
635 #[quickcheck]
639 fn monad_left_identity(a: i32) -> bool {
640 let f = |x: i32| (x.wrapping_mul(2),);
641 bind::<Tuple1Brand, _, _>(pure::<Tuple1Brand, _>(a), f) == f(a)
642 }
643
644 #[quickcheck]
646 fn monad_right_identity(m: i32) -> bool {
647 let m = (m,);
648 bind::<Tuple1Brand, _, _>(m, pure::<Tuple1Brand, _>) == m
649 }
650
651 #[quickcheck]
653 fn monad_associativity(m: i32) -> bool {
654 let m = (m,);
655 let f = |x: i32| (x.wrapping_mul(2),);
656 let g = |x: i32| (x.wrapping_add(1),);
657 bind::<Tuple1Brand, _, _>(bind::<Tuple1Brand, _, _>(m, f), g)
658 == bind::<Tuple1Brand, _, _>(m, |x| bind::<Tuple1Brand, _, _>(f(x), g))
659 }
660
661 #[test]
665 fn map_test() {
666 assert_eq!(map::<Tuple1Brand, _, _>(|x: i32| x + 1, (1,)), (2,));
667 }
668
669 #[test]
671 fn bind_test() {
672 assert_eq!(bind::<Tuple1Brand, _, _>((1,), |x| (x + 1,)), (2,));
673 }
674
675 #[test]
677 fn fold_right_test() {
678 assert_eq!(
679 crate::classes::foldable::fold_right::<RcFnBrand, Tuple1Brand, _, _>(
680 |x: i32, acc| x + acc,
681 0,
682 (1,)
683 ),
684 1
685 );
686 }
687
688 #[test]
690 fn fold_left_test() {
691 assert_eq!(
692 crate::classes::foldable::fold_left::<RcFnBrand, Tuple1Brand, _, _>(
693 |acc, x: i32| acc + x,
694 0,
695 (1,)
696 ),
697 1
698 );
699 }
700
701 #[test]
703 fn traverse_test() {
704 assert_eq!(
705 crate::classes::traversable::traverse::<Tuple1Brand, _, _, OptionBrand>(
706 |x: i32| Some(x + 1),
707 (1,)
708 ),
709 Some((2,))
710 );
711 }
712
713 #[test]
717 fn par_fold_map_test() {
718 use crate::{
719 brands::*,
720 functions::*,
721 };
722
723 let x = (1,);
724 let f = send_cloneable_fn_new::<ArcFnBrand, _, _>(|x: i32| x.to_string());
725 assert_eq!(par_fold_map::<ArcFnBrand, Tuple1Brand, _, _>(f, x), "1".to_string());
726 }
727
728 #[test]
730 fn par_fold_right_test() {
731 use crate::{
732 brands::*,
733 functions::*,
734 };
735
736 let x = (1,);
737 let f = send_cloneable_fn_new::<ArcFnBrand, _, _>(|(a, b): (i32, i32)| a + b);
738 assert_eq!(par_fold_right::<ArcFnBrand, Tuple1Brand, _, _>(f, 10, x), 11);
739 }
740}