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