90 lines
2.2 KiB
Rust
90 lines
2.2 KiB
Rust
use std::marker::PhantomData;
|
|
|
|
use super::*;
|
|
|
|
pub struct ControlFlowClass<C>(ControlFlow<(), C>);
|
|
|
|
impl<C> WeakFunctor for ControlFlowClass<C> {
|
|
type F<'a, A: 'a> = ControlFlow<A, C>
|
|
where
|
|
Self: 'a;
|
|
}
|
|
|
|
impl<C> Functor for ControlFlowClass<C> {
|
|
fn fmap<'a, A: 'a, B: 'a>(f: impl 'a + FnOnce(A) -> B, fa: Self::F<'a, A>) -> Self::F<'a, B>
|
|
where
|
|
Self: 'a,
|
|
{
|
|
match fa {
|
|
ControlFlow::Continue(c) => ControlFlow::Continue(c),
|
|
ControlFlow::Break(a) => ControlFlow::Break(f(a)),
|
|
}
|
|
}
|
|
}
|
|
|
|
impl<C> Pure for ControlFlowClass<C> {
|
|
fn pure<'a, A: 'a>(a: A) -> Self::F<'a, A>
|
|
where
|
|
Self: 'a,
|
|
{
|
|
ControlFlow::Break(a)
|
|
}
|
|
}
|
|
|
|
/// Next [Iterative] state, wrapped.
|
|
pub type IterativeWrapped<'a, G> = <<G as Iterative<'a>>::T as WeakFunctor>::F<
|
|
'a,
|
|
ControlFlow<<G as Iterative<'a>>::B, (<G as Iterative<'a>>::A, G)>,
|
|
>;
|
|
|
|
/// Value passed to [`Monad::iibind`].
|
|
pub trait Iterative<'a>: 'a + Sized {
|
|
/// [`ControlFlow::Continue`]
|
|
type A: 'a;
|
|
/// [`ControlFlow::Break`]
|
|
type B: 'a;
|
|
/// Corresponding [`WeakFunctor`].
|
|
type T: 'a + ?Sized + WeakFunctor;
|
|
/// Get next state.
|
|
fn iterate(self, a: Self::A) -> IterativeWrapped<'a, Self>;
|
|
}
|
|
|
|
pub struct BindableMut<T: ?Sized, A, B, F>(F, PhantomData<A>, PhantomData<B>, PhantomData<T>);
|
|
|
|
impl<
|
|
'a,
|
|
T: 'a + ?Sized + Functor,
|
|
A: 'a,
|
|
B: 'a,
|
|
F: 'a + FnMut(A) -> T::F<'a, ControlFlow<B, A>>,
|
|
> BindableMut<T, A, B, F>
|
|
{
|
|
pub fn new(f: F) -> Self {
|
|
BindableMut(f, PhantomData, PhantomData, PhantomData)
|
|
}
|
|
}
|
|
|
|
impl<
|
|
'a,
|
|
T: 'a + ?Sized + Functor,
|
|
A: 'a,
|
|
B: 'a,
|
|
F: 'a + FnMut(A) -> T::F<'a, ControlFlow<B, A>>,
|
|
> Iterative<'a> for BindableMut<T, A, B, F>
|
|
{
|
|
type A = A;
|
|
type B = B;
|
|
type T = T;
|
|
|
|
fn iterate(mut self, a: Self::A) -> IterativeWrapped<'a, Self> {
|
|
let fa = self.0(a);
|
|
T::fmap(
|
|
move |state| match state {
|
|
ControlFlow::Continue(next_a) => ControlFlow::Continue((next_a, self)),
|
|
ControlFlow::Break(b) => ControlFlow::Break(b),
|
|
},
|
|
fa,
|
|
)
|
|
}
|
|
}
|