effect tests
This commit is contained in:
parent
b5e5727936
commit
106fd83e33
@ -159,3 +159,89 @@ impl<'a, E: 'a + Send> LocalFunctor<'a> for EffectInstance<E> {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod effect_tests {
|
||||||
|
use super::{test_suite, tests, Effect, EffectInstance, WithEffect};
|
||||||
|
|
||||||
|
#[derive(Debug, PartialEq)]
|
||||||
|
enum TestEffect {
|
||||||
|
Pure,
|
||||||
|
Sample,
|
||||||
|
Parallel(Box<Self>, Box<Self>),
|
||||||
|
Sequential(Box<Self>, Box<Self>),
|
||||||
|
}
|
||||||
|
|
||||||
|
impl TestEffect {
|
||||||
|
fn is_pure(&self) -> bool {
|
||||||
|
matches!(self, Self::Pure)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn simplify(self) -> Self {
|
||||||
|
match self {
|
||||||
|
Self::Pure => Self::Pure,
|
||||||
|
Self::Sample => Self::Sample,
|
||||||
|
Self::Parallel(a, b) if a.is_pure() => *b,
|
||||||
|
Self::Parallel(a, b) if b.is_pure() => *a,
|
||||||
|
Self::Sequential(a, b) if a.is_pure() => *b,
|
||||||
|
Self::Sequential(a, b) if b.is_pure() => *a,
|
||||||
|
Self::Parallel(a, b) => match *a {
|
||||||
|
Self::Parallel(aa, ab) => {
|
||||||
|
Self::Parallel(aa, Self::Parallel(ab, b).into()).simplify()
|
||||||
|
}
|
||||||
|
a => Self::Parallel(a.simplify().into(), b.simplify().into()),
|
||||||
|
},
|
||||||
|
Self::Sequential(a, b) => match *a {
|
||||||
|
TestEffect::Sequential(aa, ab) => {
|
||||||
|
Self::Sequential(aa, Self::Sequential(ab, b).into()).simplify()
|
||||||
|
}
|
||||||
|
a => Self::Sequential(a.simplify().into(), b.simplify().into()),
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Effect for TestEffect {
|
||||||
|
fn e_pure() -> Self {
|
||||||
|
Self::Pure
|
||||||
|
}
|
||||||
|
|
||||||
|
fn e_parallel(el: Self, er: Self) -> Self {
|
||||||
|
Self::Parallel(el.into(), er.into())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn e_after(self, effect: Self) -> Self {
|
||||||
|
Self::Sequential(effect.into(), self.into())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
type T = EffectInstance<TestEffect>;
|
||||||
|
|
||||||
|
impl<'a> tests::Eqr<'a> for T {
|
||||||
|
fn eqr<A: 'a + Send + PartialEq + std::fmt::Debug>(
|
||||||
|
name: &'a str,
|
||||||
|
left: Self::F<A>,
|
||||||
|
right: Self::F<A>,
|
||||||
|
) -> tests::R {
|
||||||
|
tests::eqr(
|
||||||
|
name,
|
||||||
|
(left.value, left.effect.simplify()),
|
||||||
|
(right.value, right.effect.simplify()),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a> test_suite::FunctorTestSuite<'a> for T {
|
||||||
|
fn sample<A: 'a + Send, F: FnMut(&'a (dyn Send + Sync + Fn(A) -> Self::F<A>))>(mut f: F) {
|
||||||
|
f(&|a| WithEffect {
|
||||||
|
value: a,
|
||||||
|
effect: TestEffect::Sample,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn monad_follows_laws() {
|
||||||
|
test_suite::monad_follows_laws::<T>().unwrap();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user