1#[fp_macros::document_module]
45mod inner {
46 pub struct Val;
55
56 pub struct Ref;
63
64 pub trait ClosureMode {
74 type Target<'a, A: 'a, B: 'a>: ?Sized + 'a;
76
77 type SendTarget<'a, A: 'a, B: 'a>: ?Sized + 'a;
79 }
80
81 impl ClosureMode for Val {
82 type SendTarget<'a, A: 'a, B: 'a> = dyn 'a + Fn(A) -> B + Send + Sync;
83 type Target<'a, A: 'a, B: 'a> = dyn 'a + Fn(A) -> B;
84 }
85
86 impl ClosureMode for Ref {
87 type SendTarget<'a, A: 'a, B: 'a> = dyn 'a + Fn(&A) -> B + Send + Sync;
88 type Target<'a, A: 'a, B: 'a> = dyn 'a + Fn(&A) -> B;
89 }
90}
91
92pub use inner::*;
93
94pub mod alt;
95pub mod apply_first;
96pub mod apply_second;
97pub mod bifoldable;
98pub mod bifunctor;
99pub mod bitraversable;
100pub mod compactable;
101pub mod contravariant;
102pub mod filterable;
103pub mod filterable_with_index;
104pub mod foldable;
105pub mod foldable_with_index;
106pub mod functor;
107pub mod functor_with_index;
108pub mod lift;
109pub mod map_first;
110pub mod map_second;
111pub mod semiapplicative;
112pub mod semimonad;
113pub mod traversable;
114pub mod traversable_with_index;
115pub mod witherable;
116
117#[cfg(test)]
118mod tests {
119 use {
120 super::{
121 functor::explicit::map,
122 lift::explicit::lift2,
123 semimonad::explicit::bind,
124 },
125 crate::{
126 brands::*,
127 types::*,
128 },
129 };
130
131 #[test]
132 fn test_val_option_map() {
133 let result = map::<OptionBrand, _, _, _, _>(|x: i32| x * 2, Some(5));
134 assert_eq!(result, Some(10));
135 }
136
137 #[test]
138 fn test_val_vec_map() {
139 let result = map::<VecBrand, _, _, _, _>(|x: i32| x + 1, vec![1, 2, 3]);
140 assert_eq!(result, vec![2, 3, 4]);
141 }
142
143 #[test]
144 fn test_ref_lazy_map() {
145 let lazy = RcLazy::pure(10);
146 let result = map::<LazyBrand<RcLazyConfig>, _, _, _, _>(|x: &i32| *x * 2, &lazy);
147 assert_eq!(*result.evaluate(), 20);
148 }
149
150 #[test]
151 fn test_val_none_map() {
152 let result = map::<OptionBrand, i32, i32, _, _>(|x| x * 2, None);
153 assert_eq!(result, None);
154 }
155
156 #[test]
157 fn test_val_option_bind() {
158 let result = bind::<OptionBrand, _, _, _, _>(Some(5), |x: i32| Some(x * 2));
159 assert_eq!(result, Some(10));
160 }
161
162 #[test]
163 fn test_val_option_lift2() {
164 let result = lift2::<OptionBrand, _, _, _, _, _, _>(|a, b| a + b, Some(1), Some(2));
165 assert_eq!(result, Some(3));
166 }
167
168 #[test]
171 fn test_val_option_filter_map() {
172 use super::filterable::explicit::filter_map;
173 let result = filter_map::<OptionBrand, _, _, _, _>(
174 |x: i32| if x > 3 { Some(x * 2) } else { None },
175 Some(5),
176 );
177 assert_eq!(result, Some(10));
178 }
179
180 #[test]
181 fn test_val_option_filter_map_none() {
182 use super::filterable::explicit::filter_map;
183 let result = filter_map::<OptionBrand, _, _, _, _>(
184 |x: i32| if x > 10 { Some(x) } else { None },
185 Some(5),
186 );
187 assert_eq!(result, None);
188 }
189
190 #[test]
191 fn test_ref_option_filter_map() {
192 use super::filterable::explicit::filter_map;
193 let result = filter_map::<OptionBrand, _, _, _, _>(
194 |x: &i32| if *x > 3 { Some(*x * 2) } else { None },
195 &Some(5),
196 );
197 assert_eq!(result, Some(10));
198 }
199
200 #[test]
201 fn test_val_vec_filter_map() {
202 use super::filterable::explicit::filter_map;
203 let result = filter_map::<VecBrand, _, _, _, _>(
204 |x: i32| if x > 2 { Some(x * 10) } else { None },
205 vec![1, 2, 3, 4],
206 );
207 assert_eq!(result, vec![30, 40]);
208 }
209
210 #[test]
211 fn test_ref_vec_filter_map() {
212 use super::filterable::explicit::filter_map;
213 let v = vec![1, 2, 3, 4];
214 let result = filter_map::<VecBrand, _, _, _, _>(
215 |x: &i32| if *x > 2 { Some(*x * 10) } else { None },
216 &v,
217 );
218 assert_eq!(result, vec![30, 40]);
219 }
220
221 #[test]
224 fn test_val_option_traverse() {
225 use super::traversable::explicit::traverse;
226 let result = traverse::<RcFnBrand, OptionBrand, _, _, OptionBrand, _, _>(
227 |x: i32| Some(x * 2),
228 Some(5),
229 );
230 assert_eq!(result, Some(Some(10)));
231 }
232
233 #[test]
234 fn test_val_option_traverse_none() {
235 use super::traversable::explicit::traverse;
236 let result = traverse::<RcFnBrand, OptionBrand, _, _, OptionBrand, _, _>(
237 |_: i32| None::<i32>,
238 Some(5),
239 );
240 assert_eq!(result, None);
241 }
242
243 #[test]
244 fn test_ref_option_traverse() {
245 use super::traversable::explicit::traverse;
246 let result = traverse::<RcFnBrand, OptionBrand, _, _, OptionBrand, _, _>(
247 |x: &i32| Some(*x * 2),
248 &Some(5),
249 );
250 assert_eq!(result, Some(Some(10)));
251 }
252
253 #[test]
254 fn test_val_vec_traverse() {
255 use super::traversable::explicit::traverse;
256 let result: Option<Vec<i32>> = traverse::<RcFnBrand, VecBrand, _, _, OptionBrand, _, _>(
257 |x: i32| Some(x * 2),
258 vec![1, 2, 3],
259 );
260 assert_eq!(result, Some(vec![2, 4, 6]));
261 }
262
263 #[test]
264 fn test_ref_vec_traverse() {
265 use super::traversable::explicit::traverse;
266 let v = vec![1, 2, 3];
267 let result: Option<Vec<i32>> =
268 traverse::<RcFnBrand, VecBrand, _, _, OptionBrand, _, _>(|x: &i32| Some(*x * 2), &v);
269 assert_eq!(result, Some(vec![2, 4, 6]));
270 }
271
272 #[test]
275 fn test_val_option_filter() {
276 use super::filterable::explicit::filter;
277 let result = filter::<OptionBrand, _, _, _>(|x: i32| x > 3, Some(5));
278 assert_eq!(result, Some(5));
279 }
280
281 #[test]
282 fn test_ref_option_filter() {
283 use super::filterable::explicit::filter;
284 let result = filter::<OptionBrand, _, _, _>(|x: &i32| *x > 3, &Some(5));
285 assert_eq!(result, Some(5));
286 }
287
288 #[test]
289 fn test_val_vec_filter() {
290 use super::filterable::explicit::filter;
291 let result = filter::<VecBrand, _, _, _>(|x: i32| x > 3, vec![1, 2, 3, 4, 5]);
292 assert_eq!(result, vec![4, 5]);
293 }
294
295 #[test]
296 fn test_ref_vec_filter() {
297 use super::filterable::explicit::filter;
298 let v = vec![1, 2, 3, 4, 5];
299 let result = filter::<VecBrand, _, _, _>(|x: &i32| *x > 3, &v);
300 assert_eq!(result, vec![4, 5]);
301 }
302
303 #[test]
306 fn test_val_option_partition() {
307 use super::filterable::explicit::partition;
308 let (no, yes) = partition::<OptionBrand, _, _, _>(|x: i32| x > 3, Some(5));
309 assert_eq!(yes, Some(5));
310 assert_eq!(no, None);
311 }
312
313 #[test]
314 fn test_ref_option_partition() {
315 use super::filterable::explicit::partition;
316 let (no, yes) = partition::<OptionBrand, _, _, _>(|x: &i32| *x > 3, &Some(5));
317 assert_eq!(yes, Some(5));
318 assert_eq!(no, None);
319 }
320
321 #[test]
324 fn test_val_option_partition_map() {
325 use super::filterable::explicit::partition_map;
326 let (errs, oks) =
327 partition_map::<OptionBrand, _, _, _, _, _>(|x: i32| Ok::<i32, i32>(x * 2), Some(5));
328 assert_eq!(errs, None);
329 assert_eq!(oks, Some(10));
330 }
331
332 #[test]
333 fn test_ref_option_partition_map() {
334 use super::filterable::explicit::partition_map;
335 let (errs, oks) =
336 partition_map::<OptionBrand, _, _, _, _, _>(|x: &i32| Ok::<i32, i32>(*x * 2), &Some(5));
337 assert_eq!(errs, None);
338 assert_eq!(oks, Some(10));
339 }
340
341 #[test]
344 fn test_val_vec_map_with_index() {
345 use super::functor_with_index::explicit::map_with_index;
346 let result =
347 map_with_index::<VecBrand, _, _, _, _>(|i, x: i32| x + i as i32, vec![10, 20, 30]);
348 assert_eq!(result, vec![10, 21, 32]);
349 }
350
351 #[test]
352 fn test_ref_vec_map_with_index() {
353 use super::functor_with_index::explicit::map_with_index;
354 let v = vec![10, 20, 30];
355 let result = map_with_index::<VecBrand, _, _, _, _>(|i, x: &i32| *x + i as i32, &v);
356 assert_eq!(result, vec![10, 21, 32]);
357 }
358
359 #[test]
362 fn test_val_vec_filter_with_index() {
363 use super::filterable_with_index::explicit::filter_with_index;
364 let result =
365 filter_with_index::<VecBrand, _, _, _>(|i, _x: i32| i < 2, vec![10, 20, 30, 40]);
366 assert_eq!(result, vec![10, 20]);
367 }
368
369 #[test]
370 fn test_ref_vec_filter_with_index() {
371 use super::filterable_with_index::explicit::filter_with_index;
372 let v = vec![10, 20, 30, 40];
373 let result = filter_with_index::<VecBrand, _, _, _>(|i, _x: &i32| i < 2, &v);
374 assert_eq!(result, vec![10, 20]);
375 }
376
377 #[test]
380 fn test_val_vec_filter_map_with_index() {
381 use super::filterable_with_index::explicit::filter_map_with_index;
382 let result = filter_map_with_index::<VecBrand, _, _, _, _>(
383 |i, x: i32| if i % 2 == 0 { Some(x * 2) } else { None },
384 vec![10, 20, 30, 40],
385 );
386 assert_eq!(result, vec![20, 60]);
387 }
388
389 #[test]
390 fn test_ref_vec_filter_map_with_index() {
391 use super::filterable_with_index::explicit::filter_map_with_index;
392 let v = vec![10, 20, 30, 40];
393 let result = filter_map_with_index::<VecBrand, _, _, _, _>(
394 |i, x: &i32| if i % 2 == 0 { Some(*x * 2) } else { None },
395 &v,
396 );
397 assert_eq!(result, vec![20, 60]);
398 }
399
400 #[test]
403 fn test_val_vec_partition_with_index() {
404 use super::filterable_with_index::explicit::partition_with_index;
405 let (not_satisfied, satisfied) =
406 partition_with_index::<VecBrand, _, _, _>(|i, _x: i32| i < 2, vec![10, 20, 30, 40]);
407 assert_eq!(satisfied, vec![10, 20]);
408 assert_eq!(not_satisfied, vec![30, 40]);
409 }
410
411 #[test]
412 fn test_ref_vec_partition_with_index() {
413 use super::filterable_with_index::explicit::partition_with_index;
414 let v = vec![10, 20, 30, 40];
415 let (not_satisfied, satisfied) =
416 partition_with_index::<VecBrand, _, _, _>(|i, _x: &i32| i < 2, &v);
417 assert_eq!(satisfied, vec![10, 20]);
418 assert_eq!(not_satisfied, vec![30, 40]);
419 }
420
421 #[test]
424 fn test_val_vec_partition_map_with_index() {
425 use super::filterable_with_index::explicit::partition_map_with_index;
426 let (errs, oks) = partition_map_with_index::<VecBrand, _, _, _, _, _>(
427 |i, x: i32| if i < 2 { Ok(x) } else { Err(x) },
428 vec![10, 20, 30, 40],
429 );
430 assert_eq!(oks, vec![10, 20]);
431 assert_eq!(errs, vec![30, 40]);
432 }
433
434 #[test]
435 fn test_ref_vec_partition_map_with_index() {
436 use super::filterable_with_index::explicit::partition_map_with_index;
437 let v = vec![10, 20, 30, 40];
438 let (errs, oks) = partition_map_with_index::<VecBrand, _, _, _, _, _>(
439 |i, x: &i32| if i < 2 { Ok(*x) } else { Err(*x) },
440 &v,
441 );
442 assert_eq!(oks, vec![10, 20]);
443 assert_eq!(errs, vec![30, 40]);
444 }
445
446 #[test]
449 fn test_val_vec_fold_map_with_index() {
450 use super::foldable_with_index::explicit::fold_map_with_index;
451 let result = fold_map_with_index::<RcFnBrand, VecBrand, _, _, _, _>(
452 |i, x: i32| format!("{i}:{x}"),
453 vec![10, 20, 30],
454 );
455 assert_eq!(result, "0:101:202:30");
456 }
457
458 #[test]
459 fn test_ref_vec_fold_map_with_index() {
460 use super::foldable_with_index::explicit::fold_map_with_index;
461 let v = vec![10, 20, 30];
462 let result = fold_map_with_index::<RcFnBrand, VecBrand, _, _, _, _>(
463 |i, x: &i32| format!("{i}:{x}"),
464 &v,
465 );
466 assert_eq!(result, "0:101:202:30");
467 }
468
469 #[test]
472 fn test_val_vec_fold_right_with_index() {
473 use super::foldable_with_index::explicit::fold_right_with_index;
474 let result = fold_right_with_index::<RcFnBrand, VecBrand, _, _, _, _>(
475 |i, x: i32, acc: String| format!("{acc}{i}:{x},"),
476 String::new(),
477 vec![10, 20, 30],
478 );
479 assert_eq!(result, "2:30,1:20,0:10,");
480 }
481
482 #[test]
483 fn test_ref_vec_fold_right_with_index() {
484 use super::foldable_with_index::explicit::fold_right_with_index;
485 let v = vec![10, 20, 30];
486 let result = fold_right_with_index::<RcFnBrand, VecBrand, _, _, _, _>(
487 |i, x: &i32, acc: String| format!("{acc}{i}:{x},"),
488 String::new(),
489 &v,
490 );
491 assert_eq!(result, "2:30,1:20,0:10,");
492 }
493
494 #[test]
497 fn test_val_vec_fold_left_with_index() {
498 use super::foldable_with_index::explicit::fold_left_with_index;
499 let result = fold_left_with_index::<RcFnBrand, VecBrand, _, _, _, _>(
500 |i, acc: String, x: i32| format!("{acc}{i}:{x},"),
501 String::new(),
502 vec![10, 20, 30],
503 );
504 assert_eq!(result, "0:10,1:20,2:30,");
505 }
506
507 #[test]
508 fn test_ref_vec_fold_left_with_index() {
509 use super::foldable_with_index::explicit::fold_left_with_index;
510 let v = vec![10, 20, 30];
511 let result = fold_left_with_index::<RcFnBrand, VecBrand, _, _, _, _>(
512 |i, acc: String, x: &i32| format!("{acc}{i}:{x},"),
513 String::new(),
514 &v,
515 );
516 assert_eq!(result, "0:10,1:20,2:30,");
517 }
518
519 #[test]
522 fn test_val_vec_traverse_with_index() {
523 use super::traversable_with_index::explicit::traverse_with_index;
524 let result = traverse_with_index::<RcFnBrand, VecBrand, _, _, OptionBrand, _, _>(
525 |_i, x: i32| Some(x * 2),
526 vec![1, 2, 3],
527 );
528 assert_eq!(result, Some(vec![2, 4, 6]));
529 }
530
531 #[test]
532 fn test_ref_vec_traverse_with_index() {
533 use super::traversable_with_index::explicit::traverse_with_index;
534 let v = vec![1, 2, 3];
535 let result = traverse_with_index::<RcFnBrand, VecBrand, _, _, OptionBrand, _, _>(
536 |_i, x: &i32| Some(*x * 2),
537 &v,
538 );
539 assert_eq!(result, Some(vec![2, 4, 6]));
540 }
541
542 #[test]
545 fn test_val_option_wilt() {
546 use super::witherable::explicit::wilt;
547 let result = wilt::<RcFnBrand, OptionBrand, OptionBrand, _, _, _, _, _>(
548 |a: i32| Some(if a > 2 { Ok(a) } else { Err(a) }),
549 Some(5),
550 );
551 assert_eq!(result, Some((None, Some(5))));
552 }
553
554 #[test]
555 fn test_ref_vec_wilt() {
556 use super::witherable::explicit::wilt;
557 let v = vec![1, 2, 3, 4, 5];
558 let result: Option<(Vec<i32>, Vec<i32>)> =
559 wilt::<RcFnBrand, VecBrand, OptionBrand, _, _, _, _, _>(
560 |x: &i32| Some(if *x > 3 { Ok(*x) } else { Err(*x) }),
561 &v,
562 );
563 assert_eq!(result, Some((vec![1, 2, 3], vec![4, 5])));
564 }
565
566 #[test]
569 fn test_val_option_wither() {
570 use super::witherable::explicit::wither;
571 let result = wither::<RcFnBrand, OptionBrand, OptionBrand, _, _, _, _>(
572 |a: i32| Some(if a > 2 { Some(a * 2) } else { None }),
573 Some(5),
574 );
575 assert_eq!(result, Some(Some(10)));
576 }
577
578 #[test]
579 fn test_ref_vec_wither() {
580 use super::witherable::explicit::wither;
581 let v = vec![1, 2, 3, 4, 5];
582 let result: Option<Vec<i32>> = wither::<RcFnBrand, VecBrand, OptionBrand, _, _, _, _>(
583 |x: &i32| if *x > 3 { Some(Some(*x)) } else { Some(None) },
584 &v,
585 );
586 assert_eq!(result, Some(vec![4, 5]));
587 }
588
589 #[test]
592 fn test_val_result_bimap() {
593 use super::bifunctor::explicit::bimap;
594 let x = Result::<i32, i32>::Ok(5);
595 let y = bimap::<ResultBrand, _, _, _, _, _, _>((|e| e + 1, |s| s * 2), x);
596 assert_eq!(y, Ok(10));
597 }
598
599 #[test]
600 fn test_val_result_bimap_err() {
601 use super::bifunctor::explicit::bimap;
602 let x = Result::<i32, i32>::Err(3);
603 let y = bimap::<ResultBrand, _, _, _, _, _, _>((|e| e + 1, |s| s * 2), x);
604 assert_eq!(y, Err(4));
605 }
606
607 #[test]
608 fn test_ref_result_bimap() {
609 use super::bifunctor::explicit::bimap;
610 let x = Result::<i32, i32>::Ok(5);
611 let y = bimap::<ResultBrand, _, _, _, _, _, _>((|e: &i32| *e + 1, |s: &i32| *s * 2), &x);
612 assert_eq!(y, Ok(10));
613 }
614
615 #[test]
618 fn test_val_result_bi_fold_right() {
619 use super::bifoldable::explicit::bi_fold_right;
620 let x: Result<i32, i32> = Err(3);
621 let y = bi_fold_right::<RcFnBrand, ResultBrand, _, _, _, _, _>(
622 (|e, acc| acc - e, |s, acc| acc + s),
623 10,
624 x,
625 );
626 assert_eq!(y, 7);
627 }
628
629 #[test]
630 fn test_ref_result_bi_fold_right() {
631 use super::bifoldable::explicit::bi_fold_right;
632 let x: Result<i32, i32> = Err(3);
633 let y = bi_fold_right::<RcFnBrand, ResultBrand, _, _, _, _, _>(
634 (|e: &i32, acc| acc - *e, |s: &i32, acc| acc + *s),
635 10,
636 &x,
637 );
638 assert_eq!(y, 7);
639 }
640
641 #[test]
644 fn test_val_result_bi_fold_left() {
645 use super::bifoldable::explicit::bi_fold_left;
646 let x: Result<i32, i32> = Ok(5);
647 let y = bi_fold_left::<RcFnBrand, ResultBrand, _, _, _, _, _>(
648 (|acc, e| acc - e, |acc, s| acc + s),
649 10,
650 x,
651 );
652 assert_eq!(y, 15);
653 }
654
655 #[test]
656 fn test_ref_result_bi_fold_left() {
657 use super::bifoldable::explicit::bi_fold_left;
658 let x: Result<i32, i32> = Ok(5);
659 let y = bi_fold_left::<RcFnBrand, ResultBrand, _, _, _, _, _>(
660 (|acc, e: &i32| acc - *e, |acc, s: &i32| acc + *s),
661 10,
662 &x,
663 );
664 assert_eq!(y, 15);
665 }
666
667 #[test]
670 fn test_val_result_bi_fold_map() {
671 use super::bifoldable::explicit::bi_fold_map;
672 let x: Result<i32, i32> = Ok(5);
673 let y = bi_fold_map::<RcFnBrand, ResultBrand, _, _, _, _, _>(
674 (|e: i32| e.to_string(), |s: i32| s.to_string()),
675 x,
676 );
677 assert_eq!(y, "5".to_string());
678 }
679
680 #[test]
681 fn test_ref_result_bi_fold_map() {
682 use super::bifoldable::explicit::bi_fold_map;
683 let x: Result<i32, i32> = Ok(5);
684 let y = bi_fold_map::<RcFnBrand, ResultBrand, _, _, _, _, _>(
685 (|e: &i32| e.to_string(), |s: &i32| s.to_string()),
686 &x,
687 );
688 assert_eq!(y, "5".to_string());
689 }
690
691 #[test]
694 fn test_val_result_bi_traverse() {
695 use super::bitraversable::explicit::bi_traverse;
696 let x: Result<i32, i32> = Ok(5);
697 let y = bi_traverse::<RcFnBrand, ResultBrand, _, _, _, _, OptionBrand, _, _>(
698 (|e: i32| Some(e + 1), |s: i32| Some(s * 2)),
699 x,
700 );
701 assert_eq!(y, Some(Ok(10)));
702 }
703
704 #[test]
705 fn test_ref_result_bi_traverse() {
706 use super::bitraversable::explicit::bi_traverse;
707 let x: Result<i32, i32> = Ok(5);
708 let y = bi_traverse::<RcFnBrand, ResultBrand, _, _, _, _, OptionBrand, _, _>(
709 (|e: &i32| Some(*e + 1), |s: &i32| Some(*s * 2)),
710 &x,
711 );
712 assert_eq!(y, Some(Ok(10)));
713 }
714}