partial_functional/monoid/
any.rs

1use crate::semigroup::Semigroup;
2
3/// Boolean semigroup over the operator ||.
4/// ```
5/// # use partial_functional::{Any, Semigroup};
6/// assert_eq!(Any(true), Any(false).combine(Any(true)));
7/// assert_eq!(Any(true), Any(true).combine(Any(true)));
8/// assert_eq!(Any(false), Any(false).combine(Any(false)));
9/// ```
10#[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}