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