69 lines
1.9 KiB
Rust
69 lines
1.9 KiB
Rust
use std::marker::PhantomData;
|
|
#[doc(no_inline)]
|
|
pub use std::ops::ControlFlow;
|
|
|
|
use super::{weakfunctorany::WeakFunctorAny, Functor, Pure, WeakFunctor, Wrap};
|
|
|
|
pub(super) struct ControlFlowInstance<C>(ControlFlow<(), C>);
|
|
|
|
impl<C> WeakFunctorAny for ControlFlowInstance<C> {
|
|
type FAny<'a, A: 'a> = ControlFlow<A, C>
|
|
where
|
|
Self: 'a;
|
|
}
|
|
|
|
impl<'a, C: 'a> Functor<'a> for ControlFlowInstance<C> {
|
|
fn fmap<A: 'a, B: 'a>(fa: Self::F<A>, f: impl 'a + FnOnce(A) -> B) -> Self::F<B> {
|
|
match fa {
|
|
ControlFlow::Continue(c) => ControlFlow::Continue(c),
|
|
ControlFlow::Break(a) => ControlFlow::Break(f(a)),
|
|
}
|
|
}
|
|
}
|
|
|
|
impl<'a, C: 'a> Pure<'a> for ControlFlowInstance<C> {
|
|
fn pure<A: 'a>(a: A) -> Self::F<A> {
|
|
ControlFlow::Break(a)
|
|
}
|
|
}
|
|
|
|
pub struct BindableMut<T: ?Sized, A, B, F>(A, F, PhantomData<B>, PhantomData<T>);
|
|
|
|
impl<'a, T: ?Sized + Functor<'a>, A: 'a, B: 'a, F: 'a + FnMut(A) -> T::F<ControlFlow<B, A>>>
|
|
BindableMut<T, A, B, F>
|
|
{
|
|
pub fn new(a: A, f: F) -> Self {
|
|
BindableMut(a, f, PhantomData, PhantomData)
|
|
}
|
|
}
|
|
|
|
impl<'a, T: ?Sized + Functor<'a>, A: 'a, B: 'a, F: 'a + FnMut(A) -> T::F<ControlFlow<B, A>>>
|
|
Iterative<'a> for BindableMut<T, A, B, F>
|
|
{
|
|
type B = B;
|
|
type T = T;
|
|
|
|
fn next(mut self) -> IterativeWrapped<'a, Self> {
|
|
let fstate = self.1(self.0);
|
|
T::fmap(fstate, move |state| {
|
|
ControlFlow::Continue(BindableMut::new(state?, self.1))
|
|
})
|
|
}
|
|
}
|
|
|
|
/// Next [Iterative] state, wrapped.
|
|
pub type IterativeWrapped<'a, F> =
|
|
Wrap<'a, ControlFlow<<F as Iterative<'a>>::B, F>, <F as Iterative<'a>>::T>;
|
|
|
|
/// Value passed to [`Monad::iterate`].
|
|
///
|
|
/// [`Monad::iterate`]: super::Monad::iterate
|
|
pub trait Iterative<'a>: 'a + Sized {
|
|
/// [`ControlFlow::Break`].
|
|
type B: 'a;
|
|
/// Corresponding [`WeakFunctor`].
|
|
type T: ?Sized + WeakFunctor<'a>;
|
|
/// Get next state.
|
|
fn next(self) -> IterativeWrapped<'a, Self>;
|
|
}
|