iterate_can_be_expressed_via_bind
This commit is contained in:
parent
2badeb7f01
commit
d6f2c7a7fa
@ -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
|
||||
}
|
||||
|
@ -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()),
|
||||
)
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user