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