frunk_laws/
monoid_laws.rs

1//! Module that holds laws for Monoid implementations
2//!
3//! Note that you should use the semigroup_laws module to get the associative
4//! law test.
5//!
6//! # Examples
7//!
8//! ```
9//! # extern crate quickcheck;
10//! # extern crate frunk_laws;
11//! # extern crate frunk;
12//! # use quickcheck::quickcheck;
13//! # use frunk::semigroup::*;
14//! # fn main() {
15//! use frunk_laws::monoid_laws::*;
16//! quickcheck(left_identity as fn(String) -> bool);
17//! quickcheck(right_identity as fn(String) -> bool);
18//! # }
19//! ```
20use frunk::monoid::*;
21
22/// Left identity law
23///
24///   mempty <> x = x
25///
26/// # Examples
27///
28/// ```
29/// # extern crate quickcheck;
30/// # extern crate frunk_laws;
31/// # extern crate frunk;
32/// # use quickcheck::quickcheck;
33/// # use frunk::semigroup::*;
34/// # fn main() {
35/// use frunk_laws::monoid_laws::*;
36/// quickcheck(left_identity as fn(String) -> bool);
37/// # }
38/// ```
39pub fn left_identity<A: Monoid + Eq>(a: A) -> bool {
40    <A as Monoid>::empty().combine(&a) == a
41}
42
43/// Right identity law
44///
45///   x <> mempty = x
46/// # Examples
47///
48/// ```
49/// # extern crate quickcheck;
50/// # extern crate frunk_laws;
51/// # extern crate frunk;
52/// # use quickcheck::quickcheck;
53/// # use frunk::semigroup::*;
54/// # fn main() {
55/// use frunk_laws::monoid_laws::*;
56/// quickcheck(right_identity as fn(String) -> bool);
57/// # }
58/// ```
59pub fn right_identity<A: Monoid + Eq>(a: A) -> bool {
60    a.combine(&<A as Monoid>::empty()) == a
61}
62
63#[cfg(test)]
64mod tests {
65    use super::*;
66    use crate::wrapper::*;
67    use frunk::semigroup::*;
68    use quickcheck::quickcheck;
69    use std::collections::{HashMap, HashSet};
70
71    #[test]
72    fn string_id_prop() {
73        quickcheck(left_identity as fn(String) -> bool);
74        quickcheck(right_identity as fn(String) -> bool);
75    }
76
77    #[test]
78    fn option_id_prop() {
79        quickcheck(left_identity as fn(Option<String>) -> bool);
80        quickcheck(right_identity as fn(Option<String>) -> bool);
81    }
82
83    #[test]
84    fn vec_id_prop() {
85        quickcheck(left_identity as fn(Vec<String>) -> bool);
86        quickcheck(right_identity as fn(Vec<String>) -> bool);
87    }
88
89    #[test]
90    fn hashset_id_prop() {
91        quickcheck(left_identity as fn(HashSet<i32>) -> bool);
92        quickcheck(right_identity as fn(HashSet<i32>) -> bool);
93    }
94
95    #[test]
96    fn hashmap_id_prop() {
97        quickcheck(left_identity as fn(HashMap<i32, String>) -> bool);
98        quickcheck(right_identity as fn(HashMap<i32, String>) -> bool);
99    }
100
101    #[test]
102    fn any_id_prop() {
103        quickcheck(left_identity as fn(Wrapper<Any<i32>>) -> bool);
104        quickcheck(right_identity as fn(Wrapper<Any<i32>>) -> bool);
105    }
106
107    #[test]
108    fn all_id_prop() {
109        quickcheck(left_identity as fn(Wrapper<All<i32>>) -> bool);
110        quickcheck(right_identity as fn(Wrapper<All<i32>>) -> bool);
111    }
112
113    macro_rules! numeric_id_props {
114      ($($id: ident; $tr:ty,)*) => {
115
116        $(
117            #[test]
118            fn $id() {
119                quickcheck(left_identity as fn($tr) -> bool);
120                quickcheck(right_identity as fn($tr) -> bool);
121            }
122        )*
123      }
124    }
125
126    numeric_id_props! {
127        i8_id_prop; i8,
128        product_i8_id_prop; Wrapper<Product<i8>>,
129        u8_id_prop; u8,
130        product_u8_id_prop; Wrapper<Product<u8>>,
131        i16_id_prop; i16,
132        product_i16_id_prop; Wrapper<Product<i16>>,
133        u16_id_prop; u16,
134        product_u16_id_prop; Wrapper<Product<u16>>,
135        i32_id_prop; i32,
136        product_i32_id_prop; Wrapper<Product<i32>>,
137        u32_id_prop; u32,
138        product_u32_id_prop; Wrapper<Product<u32>>,
139        i64_id_prop; i64,
140        product_i64_id_prop; Wrapper<Product<i64>>,
141        u64_id_prop; u64,
142        product_u64_id_prop; Wrapper<Product<u64>>,
143        isize_id_prop; isize,
144        product_isize_id_prop; Wrapper<Product<isize>>,
145        usize_id_prop; usize,
146        product_usize_id_prop; Wrapper<Product<usize>>,
147    }
148}