partial_functional/monoid/
any.rs1use crate::semigroup::Semigroup;
2
3#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
11pub struct Any(pub bool);
12
13impl Semigroup for Any {
14 fn combine(self, rhs: Self) -> Self {
15 Self(self.0 || rhs.0)
16 }
17}
18
19impl PartialEq<bool> for Any {
20 fn eq(&self, other: &bool) -> bool {
21 self.0 == *other
22 }
23}
24
25impl PartialOrd<bool> for Any {
26 fn partial_cmp(&self, other: &bool) -> Option<std::cmp::Ordering> {
27 self.0.partial_cmp(other)
28 }
29}
30
31impl Default for Any {
32 fn default() -> Self {
33 Self(false)
34 }
35}
36
37impl From<bool> for Any {
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 Any {
53 fn arbitrary(g: &mut quickcheck::Gen) -> Self {
54 Any(<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 = Any::from(true);
65
66 assert_eq!(any, true);
67 }
68
69 #[test]
70 fn ordering_with_primitive() {
71 let any = Any::from(true);
72
73 assert_eq!(any > true, false);
74 }
75
76 #[quickcheck]
77 fn identity_property() {
78 assert_eq!(Any(false), Any::empty())
79 }
80
81 #[quickcheck]
82 fn any_is_true_if_atleast_one_is_true(vec: Vec<Any>) -> bool {
83 let left: Any = vec
84 .iter()
85 .copied()
86 .any(|x| x == Any(true))
87 .into();
88 let right = vec
89 .iter()
90 .copied()
91 .fold(Any::default(), |a, x| a.combine(x));
92
93 left == right
94 }
95
96 #[quickcheck]
97 fn associativity_property(x: Any, y: Any, z: Any) -> bool {
98 x.combine(y.combine(z)) == x.combine(y).combine(z)
99 }
100}