karpal_core/
comonad_traced.rs1use crate::hkt::HKT;
2#[cfg(any(feature = "std", feature = "alloc"))]
3use crate::hkt::TracedF;
4use crate::monoid::Monoid;
5
6pub trait ComonadTraced<M: Monoid>: HKT {
11 fn trace<A>(m: M, wa: &Self::Of<A>) -> A;
12
13 fn extract<A>(wa: &Self::Of<A>) -> A {
15 Self::trace(M::empty(), wa)
16 }
17}
18
19#[cfg(any(feature = "std", feature = "alloc"))]
20impl<M: Monoid + Clone + 'static> ComonadTraced<M> for TracedF<M> {
21 fn trace<A>(m: M, wa: &Box<dyn Fn(M) -> A>) -> A {
22 wa(m)
23 }
24}
25
26#[cfg(test)]
27mod tests {
28 use super::*;
29
30 #[test]
31 fn traced_trace() {
32 let w: Box<dyn Fn(i32) -> String> = Box::new(|m| format!("traced_{}", m));
33 assert_eq!(TracedF::<i32>::trace(5, &w), "traced_5");
34 }
35
36 #[test]
37 fn traced_extract() {
38 let w: Box<dyn Fn(i32) -> String> = Box::new(|m| format!("traced_{}", m));
39 assert_eq!(TracedF::<i32>::extract(&w), "traced_0");
41 }
42}
43
44#[cfg(test)]
45mod law_tests {
46 use super::*;
47 use proptest::prelude::*;
48
49 proptest! {
50 #[test]
52 fn traced_identity_trace(offset in any::<i16>()) {
53 let w: Box<dyn Fn(i32) -> i32> = Box::new(move |m| m + offset as i32);
54 let left = TracedF::<i32>::trace(i32::empty(), &w);
55 let right = TracedF::<i32>::extract(&w);
56 prop_assert_eq!(left, right);
57 }
58 }
59}