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