karpal_core/
comonad_env.rs1use crate::comonad::Comonad;
2use crate::hkt::EnvF;
3
4pub trait ComonadEnv<E>: Comonad {
9 fn ask<A>(wa: &Self::Of<A>) -> E;
10 fn local<A>(wa: Self::Of<A>, f: impl Fn(E) -> E) -> Self::Of<A>;
11}
12
13impl<E: Clone> ComonadEnv<E> for EnvF<E> {
14 fn ask<A>(wa: &(E, A)) -> E {
15 wa.0.clone()
16 }
17
18 fn local<A>(wa: (E, A), f: impl Fn(E) -> E) -> (E, A) {
19 (f(wa.0), wa.1)
20 }
21}
22
23#[cfg(test)]
24mod tests {
25 use super::*;
26
27 #[test]
28 fn env_ask() {
29 let w = ("hello", 42);
30 assert_eq!(EnvF::<&str>::ask(&w), "hello");
31 }
32
33 #[test]
34 fn env_local() {
35 let w = (10i32, "value");
36 let result = EnvF::<i32>::local(w, |e| e * 2);
37 assert_eq!(result, (20, "value"));
38 }
39}
40
41#[cfg(test)]
42mod law_tests {
43 use super::*;
44 use proptest::prelude::*;
45
46 proptest! {
47 #[test]
49 fn env_local_preserves_extract(e in any::<i16>(), a in any::<i32>()) {
50 let w = (e, a);
51 let localed = EnvF::<i16>::local(w, |e| e.wrapping_add(1));
52 let left = EnvF::<i16>::extract(&localed);
53 let right = EnvF::<i16>::extract(&(e, a));
54 prop_assert_eq!(left, right);
55 }
56 }
57}