local_follows_laws
All checks were successful
buildbot/cargo fmt (1.72) Build done.
buildbot/cargo clippy (1.65) Build done.
buildbot/cargo doc (1.72) Build done.
buildbot/cargo clippy (1.72) Build done.
buildbot/cargo test (1.65) Build done.

This commit is contained in:
AF 2023-10-15 18:31:40 +00:00
parent d2a021d813
commit a0c49787c8
4 changed files with 52 additions and 3 deletions

View File

@ -169,7 +169,7 @@ mod effect_tests {
#[derive(Clone, Debug, PartialEq)] #[derive(Clone, Debug, PartialEq)]
enum TestEffect { enum TestEffect {
Pure, Pure,
Sample, Sample(i32),
Parallel(Arc<Self>, Arc<Self>), Parallel(Arc<Self>, Arc<Self>),
Sequential(Arc<Self>, Arc<Self>), Sequential(Arc<Self>, Arc<Self>),
} }
@ -182,7 +182,7 @@ mod effect_tests {
fn simplify(&self) -> Arc<Self> { fn simplify(&self) -> Arc<Self> {
match self { match self {
Self::Pure => Self::Pure.into(), Self::Pure => Self::Pure.into(),
Self::Sample => Self::Sample.into(), Self::Sample(x) => Self::Sample(*x).into(),
Self::Parallel(a, b) if a.is_pure() => b.clone(), Self::Parallel(a, b) if a.is_pure() => b.clone(),
Self::Parallel(a, b) if b.is_pure() => a.clone(), Self::Parallel(a, b) if b.is_pure() => a.clone(),
Self::Sequential(a, b) if a.is_pure() => b.clone(), Self::Sequential(a, b) if a.is_pure() => b.clone(),
@ -241,7 +241,19 @@ mod effect_tests {
) { ) {
f(Arc::new(|a| WithEffect { f(Arc::new(|a| WithEffect {
value: a, value: a,
effect: TestEffect::Sample, effect: TestEffect::Sample(0),
}));
f(Arc::new(|a| WithEffect {
value: a,
effect: TestEffect::Sample(1),
}));
f(Arc::new(|a| WithEffect {
value: a,
effect: TestEffect::Sample(2),
}));
f(Arc::new(|a| WithEffect {
value: a,
effect: TestEffect::Sample(3),
})); }));
} }
} }
@ -255,4 +267,9 @@ mod effect_tests {
fn shared_follows_laws() { fn shared_follows_laws() {
test_suite::shared_follows_laws::<T>().unwrap(); test_suite::shared_follows_laws::<T>().unwrap();
} }
#[test]
fn local_follows_laws() {
test_suite::local_follows_laws::<T>().unwrap();
}
} }

View File

@ -299,4 +299,9 @@ mod result_tests {
fn fail_follows_laws() { fn fail_follows_laws() {
test_suite::fail_functor_follows_laws::<T, _>().unwrap(); test_suite::fail_functor_follows_laws::<T, _>().unwrap();
} }
#[test]
fn local_follows_laws() {
test_suite::local_follows_laws::<T>().unwrap();
}
} }

View File

@ -1,6 +1,7 @@
use std::sync::Arc; use std::sync::Arc;
use super::fail::*; use super::fail::*;
use super::local::*;
use super::shared::*; use super::shared::*;
use super::tests::*; use super::tests::*;
use super::*; use super::*;
@ -144,3 +145,13 @@ pub fn fail_functor_follows_laws<'a, T: Functor<'a> + FailTestSuite<'a, E>, E: '
}); });
res res
} }
pub fn local_follows_laws<'a, T: LocalFunctor<'a> + Monad<'a> + FunctorTestSuite<'a>>() -> R {
let mut res = R::default();
T::sample(|pa| {
T::sample(|pb| {
res += local_self_composes::<T, _>(|| pa(pb(2)));
})
});
res
}

View File

@ -3,6 +3,8 @@ use std::{
ops::{Add, AddAssign}, ops::{Add, AddAssign},
}; };
use local::LocalFunctor;
use super::applicative_select::*; use super::applicative_select::*;
use super::controlflow::*; use super::controlflow::*;
use super::fail::*; use super::fail::*;
@ -491,3 +493,17 @@ pub fn fmap_keeps_fail<
) -> R { ) -> R {
T::eqr("fmap fail", T::fmap(T::fail(e0()), f), T::fail(e0())) T::eqr("fmap fail", T::fmap(T::fail(e0()), f), T::fail(e0()))
} }
pub fn local_self_composes<
'a,
T: LocalFunctor<'a> + Monad<'a> + Eqr<'a>,
A: 'a + Send + Debug + PartialOrd,
>(
ffa0: impl Fn() -> T::F<T::F<A>>,
) -> R {
T::eqr(
"local self",
T::join(T::stuff::<_, T>(T::stuff::<_, T>(ffa0()))),
T::join(ffa0()),
)
}