1use crate::contravariant::PredicateF;
2use crate::decide::Decide;
3
4pub trait Conclude: Decide {
14 fn conclude<A: 'static>(f: impl Fn(A) -> core::convert::Infallible + 'static) -> Self::Of<A>;
15}
16
17impl Conclude for PredicateF {
18 fn conclude<A: 'static>(
19 _f: impl Fn(A) -> core::convert::Infallible + 'static,
20 ) -> Box<dyn Fn(A) -> bool> {
21 Box::new(|_| true)
25 }
26}
27
28#[cfg(test)]
29mod tests {
30 use super::*;
31
32 #[test]
33 fn predicate_conclude() {
34 let p: Box<dyn Fn(i32) -> bool> = PredicateF::conclude(|_: i32| unreachable!());
36 assert!(p(42));
39 assert!(p(-1));
40 }
41}
42
43#[cfg(test)]
44mod law_tests {
45 use super::*;
46 use proptest::prelude::*;
47
48 proptest! {
49 #[test]
51 fn predicate_left_identity(x in any::<i32>()) {
52 let fa: Box<dyn Fn(i32) -> bool> = Box::new(|a| a > 0);
53 let expected = fa(x);
54
55 let fa2: Box<dyn Fn(i32) -> bool> = Box::new(|a| a > 0);
56 let result = PredicateF::choose(
57 |a: i32| -> Result<core::convert::Infallible, i32> { Err(a) },
58 PredicateF::conclude(|i: core::convert::Infallible| -> core::convert::Infallible { i }),
59 fa2,
60 );
61 prop_assert_eq!(result(x), expected);
62 }
63
64 #[test]
66 fn predicate_right_identity(x in any::<i32>()) {
67 let fa: Box<dyn Fn(i32) -> bool> = Box::new(|a| a > 0);
68 let expected = fa(x);
69
70 let fa2: Box<dyn Fn(i32) -> bool> = Box::new(|a| a > 0);
71 let result = PredicateF::choose(
72 |a: i32| -> Result<i32, core::convert::Infallible> { Ok(a) },
73 fa2,
74 PredicateF::conclude(|i: core::convert::Infallible| -> core::convert::Infallible { i }),
75 );
76 prop_assert_eq!(result(x), expected);
77 }
78 }
79}