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: Send> WeakFunctorAny for ControlFlowInstance<C> {
type FAny<'a, A: 'a + Send>
= ControlFlow<A, C>
where
Self: 'a;
}
impl<'a, C: 'a + Send> Functor<'a> for ControlFlowInstance<C> {
fn fmap<A: 'a + Send, B: 'a + Send>(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 + Send> Pure<'a> for ControlFlowInstance<C> {
fn pure<A: 'a + Send>(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 + Send,
B: 'a + Send,
F: 'a + Send + 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 + Send,
B: 'a + Send,
F: 'a + Send + 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))
})
}
}
pub type IterativeWrapped<'a, F> =
Wrap<'a, ControlFlow<<F as Iterative<'a>>::B, F>, <F as Iterative<'a>>::T>;
pub trait Iterative<'a>: 'a + Send + Sized {
type B: 'a + Send;
type T: ?Sized + WeakFunctor<'a>;
fn next(self) -> IterativeWrapped<'a, Self>;
}