1use crate::alt::Alt;
2use crate::hkt::OptionF;
3#[cfg(any(feature = "std", feature = "alloc"))]
4use crate::hkt::VecF;
5#[cfg(all(not(feature = "std"), feature = "alloc"))]
6use alloc::vec::Vec;
7
8pub trait Plus: Alt {
15 fn zero<A>() -> Self::Of<A>;
16}
17
18impl Plus for OptionF {
19 fn zero<A>() -> Option<A> {
20 None
21 }
22}
23
24#[cfg(any(feature = "std", feature = "alloc"))]
27impl Plus for VecF {
28 fn zero<A>() -> Vec<A> {
29 Vec::new()
30 }
31}
32
33#[cfg(test)]
34mod tests {
35 use super::*;
36
37 #[test]
38 fn option_zero() {
39 assert_eq!(OptionF::zero::<i32>(), None);
40 }
41
42 #[test]
43 fn vec_zero() {
44 assert_eq!(VecF::zero::<i32>(), Vec::<i32>::new());
45 }
46}
47
48#[cfg(test)]
49mod law_tests {
50 use super::*;
51 use crate::alt::Alt;
52 use crate::functor::Functor;
53 use proptest::prelude::*;
54
55 proptest! {
56 #[test]
58 fn option_left_identity(a in any::<Option<i32>>()) {
59 let left = OptionF::alt(OptionF::zero(), a);
60 prop_assert_eq!(left, a);
61 }
62
63 #[test]
65 fn option_right_identity(a in any::<Option<i32>>()) {
66 let left = OptionF::alt(a, OptionF::zero());
67 prop_assert_eq!(left, a);
68 }
69
70 #[test]
72 fn option_annihilation(_x in any::<i32>()) {
73 let f = |a: i32| a.wrapping_add(1);
74 let left = OptionF::fmap(OptionF::zero::<i32>(), f);
75 let right = OptionF::zero::<i32>();
76 prop_assert_eq!(left, right);
77 }
78
79 #[test]
80 fn vec_left_identity(a in prop::collection::vec(any::<i32>(), 0..10)) {
81 let left = VecF::alt(VecF::zero(), a.clone());
82 prop_assert_eq!(left, a);
83 }
84
85 #[test]
86 fn vec_right_identity(a in prop::collection::vec(any::<i32>(), 0..10)) {
87 let left = VecF::alt(a.clone(), VecF::zero());
88 prop_assert_eq!(left, a);
89 }
90 }
91}