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