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