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

This commit is contained in:
AF 2023-10-15 15:50:55 +00:00
parent 2badeb7f01
commit d6f2c7a7fa
2 changed files with 44 additions and 0 deletions

View File

@ -88,5 +88,10 @@ pub fn monad_follows_laws<'a, T: Monad<'a> + FunctorTestSuite<'a>>() -> R {
res += join_can_be_expressed_via_bind::<T, _>(|| pa(pb(2)));
})
});
T::sample(|pa| {
T::sample(|pb| {
res += iterate_can_be_expressed_via_bind::<T, _, _, _>(|| pa(2), || |x| pb(x + 3));
})
});
res
}

View File

@ -3,6 +3,8 @@ use std::{
ops::{Add, AddAssign},
};
use controlflow::IterativeWrapped;
use super::*;
pub struct TestResults {
@ -361,3 +363,40 @@ pub fn join_can_be_expressed_via_bind<
T::bind(ffa0(), |fa| fa),
)
}
enum TestIterative<'a, T: Monad<'a>, A: 'a + Send, B: 'a + Send, F: 'a + FnOnce(A) -> T::F<B>> {
Pre(T::F<A>, F),
Post(T::F<B>),
}
impl<'a, T: Monad<'a>, A: 'a + Send, B: 'a + Send, F: 'a + Send + FnOnce(A) -> T::F<B>>
Iterative<'a> for TestIterative<'a, T, A, B, F>
{
type B = B;
type T = T;
fn next(self) -> IterativeWrapped<'a, Self> {
match self {
Self::Pre(fa, f) => T::fmap(fa, |a| ControlFlow::Continue(Self::Post(f(a)))),
Self::Post(fb) => T::fmap(fb, ControlFlow::Break),
}
}
}
pub fn iterate_can_be_expressed_via_bind<
'a,
T: Monad<'a> + Eqr<'a>,
A: 'a + Send,
B: 'a + Send + Debug + PartialEq,
F: 'a + Send + Fn(A) -> T::F<B>,
>(
fa0: impl 'a + Fn() -> T::F<A>,
f0: impl 'a + Fn() -> F,
) -> R {
T::eqr(
"iterate via bind",
T::iterate(TestIterative::Pre(fa0(), f0())),
T::bind(fa0(), f0()),
)
}