1use crate::contravariant::PredicateF;
2use crate::divide::Divide;
3
4pub trait Divisible: Divide {
12 fn conquer<A: 'static>() -> Self::Of<A>;
13}
14
15impl Divisible for PredicateF {
16 fn conquer<A: 'static>() -> Box<dyn Fn(A) -> bool> {
17 Box::new(|_| true)
18 }
19}
20
21#[cfg(test)]
22mod tests {
23 use super::*;
24
25 #[test]
26 fn predicate_conquer() {
27 let p: Box<dyn Fn(i32) -> bool> = PredicateF::conquer();
28 assert!(p(42));
29 assert!(p(-1));
30 assert!(p(0));
31 }
32}
33
34#[cfg(test)]
35mod law_tests {
36 use super::*;
37 use proptest::prelude::*;
38
39 proptest! {
40 #[test]
42 fn predicate_left_identity(x in any::<i32>()) {
43 let fa: Box<dyn Fn(i32) -> bool> = Box::new(|a| a > 0);
44 let expected = fa(x);
45
46 let fa2: Box<dyn Fn(i32) -> bool> = Box::new(|a| a > 0);
47 let result = PredicateF::divide(
48 |a: i32| ((), a),
49 PredicateF::conquer::<()>(),
50 fa2,
51 );
52 prop_assert_eq!(result(x), expected);
53 }
54
55 #[test]
57 fn predicate_right_identity(x in any::<i32>()) {
58 let fa: Box<dyn Fn(i32) -> bool> = Box::new(|a| a > 0);
59 let expected = fa(x);
60
61 let fa2: Box<dyn Fn(i32) -> bool> = Box::new(|a| a > 0);
62 let result = PredicateF::divide(
63 |a: i32| (a, ()),
64 fa2,
65 PredicateF::conquer::<()>(),
66 );
67 prop_assert_eq!(result(x), expected);
68 }
69 }
70}