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