partial_functional/monoid/
all.rs1use crate::semigroup::Semigroup;
2
3#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
11pub struct All(pub bool);
12
13impl Semigroup for All {
14 fn combine(self, rhs: Self) -> Self {
15 Self(self.0 && rhs.0)
16 }
17}
18
19impl Default for All {
20 fn default() -> Self {
21 Self(true)
22 }
23}
24
25impl PartialEq<bool> for All {
26 fn eq(&self, other: &bool) -> bool {
27 self.0 == *other
28 }
29}
30
31impl PartialOrd<bool> for All {
32 fn partial_cmp(&self, other: &bool) -> Option<std::cmp::Ordering> {
33 self.0.partial_cmp(other)
34 }
35}
36
37impl From<bool> for All {
38 fn from(value: bool) -> Self {
39 Self(value)
40 }
41}
42
43#[cfg(test)]
44mod tests {
45 use crate::monoid::Monoid;
46
47 use super::*;
48
49 use quickcheck::Arbitrary;
50 use quickcheck_macros::quickcheck;
51
52 impl Arbitrary for All {
53 fn arbitrary(g: &mut quickcheck::Gen) -> Self {
54 All(<bool>::arbitrary(g))
55 }
56
57 fn shrink(&self) -> Box<dyn Iterator<Item = Self>> {
58 Box::new(<bool>::shrink(&self.0).map(|x| x.into()))
59 }
60 }
61
62 #[test]
63 fn equality_with_primitive() {
64 let any = All::from(true);
65
66 assert_eq!(any, true);
67 }
68
69 #[test]
70 fn ordering_with_primitive() {
71 let any = All::from(true);
72
73 assert_eq!(any > true, false);
74 }
75
76 #[quickcheck]
77 fn identity_property() {
78 assert_eq!(All(true), All::empty())
79 }
80
81 #[quickcheck]
82 fn any_is_true_if_atleast_one_is_true(vec: Vec<All>) -> bool {
83 let left: All = vec
84 .iter()
85 .copied()
86 .all(|x| x == All(true))
87 .into();
88 let right = vec
89 .iter()
90 .copied()
91 .fold(All::default(), |a, x| a.combine(x));
92
93 left == right
94 }
95
96 #[quickcheck]
97 fn associativity_property(x: All, y: All, z: All) -> bool {
98 x.combine(y.combine(z)) == x.combine(y).combine(z)
99 }
100}