parent
							
								
									b05326089d
								
							
						
					
					
						commit
						73e9b9efb3
					
				
							
								
								
									
										16
									
								
								src/func.rs
									
									
									
									
									
								
							
							
						
						
									
										16
									
								
								src/func.rs
									
									
									
									
									
								
							| @ -9,18 +9,20 @@ | |||||||
| 
 | 
 | ||||||
| pub mod classes; | pub mod classes; | ||||||
| pub mod clone_func; | pub mod clone_func; | ||||||
|  | mod controlflow; | ||||||
| pub mod copy_func; | pub mod copy_func; | ||||||
| pub mod derivations; | pub mod derivations; | ||||||
| mod istate; |  | ||||||
| #[cfg(test)] | #[cfg(test)] | ||||||
| pub mod test_suite; | pub mod test_suite; | ||||||
| #[cfg(test)] | #[cfg(test)] | ||||||
| pub mod tests; | pub mod tests; | ||||||
| 
 | 
 | ||||||
| pub use self::istate::IState; | pub use std::ops::ControlFlow; | ||||||
| use self::istate::IStateClass; | 
 | ||||||
| pub use radn_derive::{CovariantFunctor, SharedFunctor}; | pub use radn_derive::{CovariantFunctor, SharedFunctor}; | ||||||
| 
 | 
 | ||||||
|  | pub use self::controlflow::ControlFlowClass; | ||||||
|  | 
 | ||||||
| /// Part of Haskell's `Functor f` responsible to use `f a`.
 | /// Part of Haskell's `Functor f` responsible to use `f a`.
 | ||||||
| ///
 | ///
 | ||||||
| /// <https://hackage.haskell.org/package/base-4.18.0.0/docs/Data-Functor.html>
 | /// <https://hackage.haskell.org/package/base-4.18.0.0/docs/Data-Functor.html>
 | ||||||
| @ -177,7 +179,7 @@ pub trait Monad: Applicative { | |||||||
|     /// On practice, you shouldn't be using [`Monad::bind`]/[`Pure::pure`]/[`Functor::fmap`] here.
 |     /// On practice, you shouldn't be using [`Monad::bind`]/[`Pure::pure`]/[`Functor::fmap`] here.
 | ||||||
|     fn ibind<'a, A: 'a, B: 'a>( |     fn ibind<'a, A: 'a, B: 'a>( | ||||||
|         a: A, |         a: A, | ||||||
|         f: impl 'a + FnMut(A) -> Self::F<'a, IState<A, B>>, |         f: impl 'a + FnMut(A) -> Self::F<'a, ControlFlow<B, A>>, | ||||||
|     ) -> Self::F<'a, B> |     ) -> Self::F<'a, B> | ||||||
|     where |     where | ||||||
|         Self: 'a; |         Self: 'a; | ||||||
| @ -222,11 +224,13 @@ pub trait Alternative: Applicative { | |||||||
| /// Represents wrapped results which are instantly available.
 | /// Represents wrapped results which are instantly available.
 | ||||||
| pub trait LocalFunctor: WeakFunctor { | pub trait LocalFunctor: WeakFunctor { | ||||||
|     /// Extract iteration state, if successful.
 |     /// Extract iteration state, if successful.
 | ||||||
|     fn unstuff<'a, A: 'a, B: 'a>(state: Self::F<'a, IState<A, B>>) -> IState<A, Self::F<'a, B>> |     fn unstuff<'a, A: 'a, B: 'a>( | ||||||
|  |         state: Self::F<'a, ControlFlow<B, A>>, | ||||||
|  |     ) -> ControlFlow<Self::F<'a, B>, A> | ||||||
|     where |     where | ||||||
|         Self: 'a, |         Self: 'a, | ||||||
|     { |     { | ||||||
|         Self::stuff::<_, IStateClass<A>>(state) |         Self::stuff::<_, ControlFlowClass<A>>(state) | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     /// Stuff wrapped result into another functor.
 |     /// Stuff wrapped result into another functor.
 | ||||||
|  | |||||||
| @ -101,7 +101,7 @@ impl<U: Monad, V: Monad + LocalFunctor> Monad for CompositionClass<U, V> { | |||||||
| 
 | 
 | ||||||
|     fn ibind<'a, A: 'a, B: 'a>( |     fn ibind<'a, A: 'a, B: 'a>( | ||||||
|         a: A, |         a: A, | ||||||
|         mut f: impl 'a + FnMut(A) -> Self::F<'a, IState<A, B>>, |         mut f: impl 'a + FnMut(A) -> Self::F<'a, ControlFlow<B, A>>, | ||||||
|     ) -> Self::F<'a, B> |     ) -> Self::F<'a, B> | ||||||
|     where |     where | ||||||
|         Self: 'a, |         Self: 'a, | ||||||
| @ -132,7 +132,9 @@ impl<E, U: Monad, V: MonadFail<E> + LocalFunctor> MonadFail<E> for CompositionCl | |||||||
| } | } | ||||||
| 
 | 
 | ||||||
| impl<U: LocalFunctor + Functor, V: LocalFunctor> LocalFunctor for CompositionClass<U, V> { | impl<U: LocalFunctor + Functor, V: LocalFunctor> LocalFunctor for CompositionClass<U, V> { | ||||||
|     fn unstuff<'a, A: 'a, B: 'a>(state: Self::F<'a, IState<A, B>>) -> IState<A, Self::F<'a, B>> |     fn unstuff<'a, A: 'a, B: 'a>( | ||||||
|  |         state: Self::F<'a, ControlFlow<B, A>>, | ||||||
|  |     ) -> ControlFlow<Self::F<'a, B>, A> | ||||||
|     where |     where | ||||||
|         Self: 'a, |         Self: 'a, | ||||||
|     { |     { | ||||||
|  | |||||||
| @ -89,7 +89,7 @@ impl Monad for FutureClass { | |||||||
| 
 | 
 | ||||||
|     fn ibind<'a, A: 'a, B: 'a>( |     fn ibind<'a, A: 'a, B: 'a>( | ||||||
|         mut a: A, |         mut a: A, | ||||||
|         mut f: impl 'a + FnMut(A) -> Self::F<'a, IState<A, B>>, |         mut f: impl 'a + FnMut(A) -> Self::F<'a, ControlFlow<B, A>>, | ||||||
|     ) -> Self::F<'a, B> |     ) -> Self::F<'a, B> | ||||||
|     where |     where | ||||||
|         Self: 'a, |         Self: 'a, | ||||||
| @ -97,8 +97,8 @@ impl Monad for FutureClass { | |||||||
|         Box::pin(async move { |         Box::pin(async move { | ||||||
|             loop { |             loop { | ||||||
|                 match f(a).await { |                 match f(a).await { | ||||||
|                     IState::Pending(next_a) => a = next_a, |                     ControlFlow::Continue(next_a) => a = next_a, | ||||||
|                     IState::Done(b) => return b, |                     ControlFlow::Break(b) => return b, | ||||||
|                 }; |                 }; | ||||||
|             } |             } | ||||||
|         }) |         }) | ||||||
|  | |||||||
| @ -90,15 +90,15 @@ impl Monad for LazyClass { | |||||||
| 
 | 
 | ||||||
|     fn ibind<'a, A: 'a, B: 'a>( |     fn ibind<'a, A: 'a, B: 'a>( | ||||||
|         mut a: A, |         mut a: A, | ||||||
|         mut f: impl 'a + FnMut(A) -> Self::F<'a, IState<A, B>>, |         mut f: impl 'a + FnMut(A) -> Self::F<'a, ControlFlow<B, A>>, | ||||||
|     ) -> Self::F<'a, B> |     ) -> Self::F<'a, B> | ||||||
|     where |     where | ||||||
|         Self: 'a, |         Self: 'a, | ||||||
|     { |     { | ||||||
|         Box::new(move || loop { |         Box::new(move || loop { | ||||||
|             match f(a)() { |             match f(a)() { | ||||||
|                 IState::Pending(next_a) => a = next_a, |                 ControlFlow::Continue(next_a) => a = next_a, | ||||||
|                 IState::Done(b) => return b, |                 ControlFlow::Break(b) => return b, | ||||||
|             }; |             }; | ||||||
|         }) |         }) | ||||||
|     } |     } | ||||||
|  | |||||||
| @ -94,15 +94,15 @@ impl Monad for OptionClass { | |||||||
| 
 | 
 | ||||||
|     fn ibind<'a, A: 'a, B: 'a>( |     fn ibind<'a, A: 'a, B: 'a>( | ||||||
|         mut a: A, |         mut a: A, | ||||||
|         mut f: impl 'a + FnMut(A) -> Self::F<'a, IState<A, B>>, |         mut f: impl 'a + FnMut(A) -> Self::F<'a, ControlFlow<B, A>>, | ||||||
|     ) -> Self::F<'a, B> |     ) -> Self::F<'a, B> | ||||||
|     where |     where | ||||||
|         Self: 'a, |         Self: 'a, | ||||||
|     { |     { | ||||||
|         loop { |         loop { | ||||||
|             match f(a)? { |             match f(a)? { | ||||||
|                 IState::Pending(next_a) => a = next_a, |                 ControlFlow::Continue(next_a) => a = next_a, | ||||||
|                 IState::Done(b) => return Self::pure(b), |                 ControlFlow::Break(b) => return Self::pure(b), | ||||||
|             }; |             }; | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
| @ -113,14 +113,16 @@ impl Monad for OptionClass { | |||||||
| } | } | ||||||
| 
 | 
 | ||||||
| impl LocalFunctor for OptionClass { | impl LocalFunctor for OptionClass { | ||||||
|     fn unstuff<'a, A: 'a, B: 'a>(state: Self::F<'a, IState<A, B>>) -> IState<A, Self::F<'a, B>> |     fn unstuff<'a, A: 'a, B: 'a>( | ||||||
|  |         state: Self::F<'a, ControlFlow<B, A>>, | ||||||
|  |     ) -> ControlFlow<Self::F<'a, B>, A> | ||||||
|     where |     where | ||||||
|         Self: 'a, |         Self: 'a, | ||||||
|     { |     { | ||||||
|         match state { |         match state { | ||||||
|             Some(IState::Pending(a)) => IState::Pending(a), |             Some(ControlFlow::Continue(a)) => ControlFlow::Continue(a), | ||||||
|             Some(IState::Done(b)) => IState::Done(Some(b)), |             Some(ControlFlow::Break(b)) => ControlFlow::Break(Some(b)), | ||||||
|             None => IState::Done(None), |             None => ControlFlow::Break(None), | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -115,15 +115,15 @@ impl<E> Monad for ResultClass<E> { | |||||||
| 
 | 
 | ||||||
|     fn ibind<'a, A: 'a, B: 'a>( |     fn ibind<'a, A: 'a, B: 'a>( | ||||||
|         mut a: A, |         mut a: A, | ||||||
|         mut f: impl 'a + FnMut(A) -> Self::F<'a, IState<A, B>>, |         mut f: impl 'a + FnMut(A) -> Self::F<'a, ControlFlow<B, A>>, | ||||||
|     ) -> Self::F<'a, B> |     ) -> Self::F<'a, B> | ||||||
|     where |     where | ||||||
|         Self: 'a, |         Self: 'a, | ||||||
|     { |     { | ||||||
|         loop { |         loop { | ||||||
|             match f(a)? { |             match f(a)? { | ||||||
|                 IState::Pending(next_a) => a = next_a, |                 ControlFlow::Continue(next_a) => a = next_a, | ||||||
|                 IState::Done(b) => return Self::pure(b), |                 ControlFlow::Break(b) => return Self::pure(b), | ||||||
|             }; |             }; | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
| @ -137,14 +137,16 @@ impl<E> Monad for ResultClass<E> { | |||||||
| } | } | ||||||
| 
 | 
 | ||||||
| impl<E> LocalFunctor for ResultClass<E> { | impl<E> LocalFunctor for ResultClass<E> { | ||||||
|     fn unstuff<'a, A: 'a, B: 'a>(state: Self::F<'a, IState<A, B>>) -> IState<A, Self::F<'a, B>> |     fn unstuff<'a, A: 'a, B: 'a>( | ||||||
|  |         state: Self::F<'a, ControlFlow<B, A>>, | ||||||
|  |     ) -> ControlFlow<Self::F<'a, B>, A> | ||||||
|     where |     where | ||||||
|         Self: 'a, |         Self: 'a, | ||||||
|     { |     { | ||||||
|         match state { |         match state { | ||||||
|             Ok(IState::Pending(a)) => IState::Pending(a), |             Ok(ControlFlow::Continue(a)) => ControlFlow::Continue(a), | ||||||
|             Ok(IState::Done(b)) => IState::Done(Ok(b)), |             Ok(ControlFlow::Break(b)) => ControlFlow::Break(Ok(b)), | ||||||
|             Err(e) => IState::Done(Err(e)), |             Err(e) => ControlFlow::Break(Err(e)), | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -82,15 +82,15 @@ impl Monad for SoloClass { | |||||||
| 
 | 
 | ||||||
|     fn ibind<'a, A: 'a, B: 'a>( |     fn ibind<'a, A: 'a, B: 'a>( | ||||||
|         mut a: A, |         mut a: A, | ||||||
|         mut f: impl 'a + FnMut(A) -> Self::F<'a, IState<A, B>>, |         mut f: impl 'a + FnMut(A) -> Self::F<'a, ControlFlow<B, A>>, | ||||||
|     ) -> Self::F<'a, B> |     ) -> Self::F<'a, B> | ||||||
|     where |     where | ||||||
|         Self: 'a, |         Self: 'a, | ||||||
|     { |     { | ||||||
|         loop { |         loop { | ||||||
|             match f(a) { |             match f(a) { | ||||||
|                 IState::Pending(next_a) => a = next_a, |                 ControlFlow::Continue(next_a) => a = next_a, | ||||||
|                 IState::Done(b) => return b, |                 ControlFlow::Break(b) => return b, | ||||||
|             }; |             }; | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
| @ -101,7 +101,9 @@ impl Monad for SoloClass { | |||||||
| } | } | ||||||
| 
 | 
 | ||||||
| impl LocalFunctor for SoloClass { | impl LocalFunctor for SoloClass { | ||||||
|     fn unstuff<'a, A: 'a, B: 'a>(state: Self::F<'a, IState<A, B>>) -> IState<A, Self::F<'a, B>> |     fn unstuff<'a, A: 'a, B: 'a>( | ||||||
|  |         state: Self::F<'a, ControlFlow<B, A>>, | ||||||
|  |     ) -> ControlFlow<Self::F<'a, B>, A> | ||||||
|     where |     where | ||||||
|         Self: 'a, |         Self: 'a, | ||||||
|     { |     { | ||||||
|  | |||||||
| @ -226,15 +226,15 @@ impl Monad for StacklessClass { | |||||||
| 
 | 
 | ||||||
|     fn ibind<'a, A: 'a, B: 'a>( |     fn ibind<'a, A: 'a, B: 'a>( | ||||||
|         a: A, |         a: A, | ||||||
|         mut f: impl 'a + FnMut(A) -> Self::F<'a, IState<A, B>>, |         mut f: impl 'a + FnMut(A) -> Self::F<'a, ControlFlow<B, A>>, | ||||||
|     ) -> Self::F<'a, B> |     ) -> Self::F<'a, B> | ||||||
|     where |     where | ||||||
|         Self: 'a, |         Self: 'a, | ||||||
|     { |     { | ||||||
|         Self::pure(a).bind(move |a| { |         Self::pure(a).bind(move |a| { | ||||||
|             f(a).bind(|state| match state { |             f(a).bind(|state| match state { | ||||||
|                 IState::Pending(a) => Self::ibind(a, f), |                 ControlFlow::Continue(a) => Self::ibind(a, f), | ||||||
|                 IState::Done(b) => Self::pure(b), |                 ControlFlow::Break(b) => Self::pure(b), | ||||||
|             }) |             }) | ||||||
|         }) |         }) | ||||||
|     } |     } | ||||||
|  | |||||||
							
								
								
									
										30
									
								
								src/func/controlflow.rs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										30
									
								
								src/func/controlflow.rs
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,30 @@ | |||||||
|  | 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) | ||||||
|  |     } | ||||||
|  | } | ||||||
| @ -1,44 +0,0 @@ | |||||||
| use super::*; |  | ||||||
| 
 |  | ||||||
| /// Represents iteration state. Used in [`Monad::ibind`].
 |  | ||||||
| ///
 |  | ||||||
| /// [`IState<P, D>`] is isomorphic to [`Result<D, P>`].
 |  | ||||||
| pub enum IState<P, D> { |  | ||||||
|     /// Loop running.
 |  | ||||||
|     ///
 |  | ||||||
|     /// Isomorphic to [`Result::Err`].
 |  | ||||||
|     Pending(P), |  | ||||||
|     /// Loop finished.
 |  | ||||||
|     ///
 |  | ||||||
|     /// Isomorphic to [`Result::Ok`].
 |  | ||||||
|     Done(D), |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| pub struct IStateClass<P>(P); |  | ||||||
| 
 |  | ||||||
| impl<P> WeakFunctor for IStateClass<P> { |  | ||||||
|     type F<'a, A: 'a> = IState<P, A> |  | ||||||
|     where |  | ||||||
|         Self: 'a; |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| impl<P> Functor for IStateClass<P> { |  | ||||||
|     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 { |  | ||||||
|             IState::Pending(p) => IState::Pending(p), |  | ||||||
|             IState::Done(d) => IState::Done(f(d)), |  | ||||||
|         } |  | ||||||
|     } |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| impl<P> Pure for IStateClass<P> { |  | ||||||
|     fn pure<'a, A: 'a>(a: A) -> Self::F<'a, A> |  | ||||||
|     where |  | ||||||
|         Self: 'a, |  | ||||||
|     { |  | ||||||
|         IState::Done(a) |  | ||||||
|     } |  | ||||||
| } |  | ||||||
| @ -158,17 +158,17 @@ impl<'a, Ctx: 'a + Context, A: Mentionable<'a, Ctx>> ExtStack<'a, Ctx, A> for St | |||||||
|     } |     } | ||||||
|     fn vec(self) -> StackVecWrapped<'a, Ctx, A> { |     fn vec(self) -> StackVecWrapped<'a, Ctx, A> { | ||||||
|         Ctx::T::ibind((vec![], self), |(mut vec, stack)| match stack { |         Ctx::T::ibind((vec![], self), |(mut vec, stack)| match stack { | ||||||
|             Nullable::Null(_) => Ctx::T::pure(IState::Done(Ok(vec))), |             Nullable::Null(_) => Ctx::T::pure(ControlFlow::Break(Ok(vec))), | ||||||
|             Nullable::NotNull(point) => Ctx::T::fmap( |             Nullable::NotNull(point) => Ctx::T::fmap( | ||||||
|                 |resolved| { |                 |resolved| { | ||||||
|                     let node = match resolved { |                     let node = match resolved { | ||||||
|                         Ok(node) => node, |                         Ok(node) => node, | ||||||
|                         Err(error) => { |                         Err(error) => { | ||||||
|                             return IState::Done(Err(error)); |                             return ControlFlow::Break(Err(error)); | ||||||
|                         } |                         } | ||||||
|                     }; |                     }; | ||||||
|                     vec.push(node.element.clone()); |                     vec.push(node.element.clone()); | ||||||
|                     IState::Pending((vec, node.rest.clone())) |                     ControlFlow::Continue((vec, node.rest.clone())) | ||||||
|                 }, |                 }, | ||||||
|                 point.resolve(), |                 point.resolve(), | ||||||
|             ), |             ), | ||||||
|  | |||||||
| @ -165,7 +165,7 @@ impl Monad for TracedClass { | |||||||
| 
 | 
 | ||||||
|     fn ibind<'a, A: 'a, B: 'a>( |     fn ibind<'a, A: 'a, B: 'a>( | ||||||
|         mut a: A, |         mut a: A, | ||||||
|         mut f: impl 'a + FnMut(A) -> Self::F<'a, IState<A, B>>, |         mut f: impl 'a + FnMut(A) -> Self::F<'a, ControlFlow<B, A>>, | ||||||
|     ) -> Self::F<'a, B> |     ) -> Self::F<'a, B> | ||||||
|     where |     where | ||||||
|         Self: 'a, |         Self: 'a, | ||||||
| @ -175,8 +175,8 @@ impl Monad for TracedClass { | |||||||
|             let fa = f(a); |             let fa = f(a); | ||||||
|             t = fa.t.after(t); |             t = fa.t.after(t); | ||||||
|             match fa.a { |             match fa.a { | ||||||
|                 IState::Pending(next_a) => a = next_a, |                 ControlFlow::Continue(next_a) => a = next_a, | ||||||
|                 IState::Done(b) => return b.with_trace(t), |                 ControlFlow::Break(b) => return b.with_trace(t), | ||||||
|             } |             } | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
|  | |||||||
| @ -147,7 +147,7 @@ impl Monad for CountedClass { | |||||||
| 
 | 
 | ||||||
|     fn ibind<'a, A: 'a, B: 'a>( |     fn ibind<'a, A: 'a, B: 'a>( | ||||||
|         mut a: A, |         mut a: A, | ||||||
|         mut f: impl 'a + FnMut(A) -> Self::F<'a, IState<A, B>>, |         mut f: impl 'a + FnMut(A) -> Self::F<'a, ControlFlow<B, A>>, | ||||||
|     ) -> Self::F<'a, B> |     ) -> Self::F<'a, B> | ||||||
|     where |     where | ||||||
|         Self: 'a, |         Self: 'a, | ||||||
| @ -157,8 +157,8 @@ impl Monad for CountedClass { | |||||||
|             let fa = f(a); |             let fa = f(a); | ||||||
|             n += fa.n; |             n += fa.n; | ||||||
|             match fa.a { |             match fa.a { | ||||||
|                 IState::Pending(next_a) => a = next_a, |                 ControlFlow::Continue(next_a) => a = next_a, | ||||||
|                 IState::Done(b) => return b.with_count(n), |                 ControlFlow::Break(b) => return b.with_count(n), | ||||||
|             } |             } | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
|  | |||||||
		Loading…
	
		Reference in New Issue
	
	Block a user