TryFutureClass + FutureFailAny
This commit is contained in:
		
							parent
							
								
									21e4496201
								
							
						
					
					
						commit
						8a384caab0
					
				| @ -26,3 +26,4 @@ pub mod option; | ||||
| pub mod result; | ||||
| pub mod solo; | ||||
| pub mod stackless; | ||||
| pub mod tryfuture; | ||||
|  | ||||
							
								
								
									
										261
									
								
								src/func/classes/tryfuture.rs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										261
									
								
								src/func/classes/tryfuture.rs
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,261 @@ | ||||
| use std::{future::Future, pin::Pin}; | ||||
| 
 | ||||
| use futures::{future::Shared, try_join, FutureExt}; | ||||
| 
 | ||||
| use crate::func::*; | ||||
| 
 | ||||
| #[derive(CovariantFunctor)] | ||||
| pub struct TryFutureClass<E>(E); | ||||
| 
 | ||||
| impl<E> WeakFunctor for TryFutureClass<E> { | ||||
|     type F<'a, A: 'a> = Pin<Box<dyn 'a + Future<Output = Result<A, E>>>> where Self: 'a; | ||||
| } | ||||
| 
 | ||||
| impl<E> Functor for TryFutureClass<E> { | ||||
|     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, | ||||
|     { | ||||
|         Box::pin(async { Ok(f(fa.await?)) }) | ||||
|     } | ||||
| 
 | ||||
|     fn replace<'a, A: 'a, B: 'a>(fa: Self::F<'a, A>, b: B) -> Self::F<'a, B> | ||||
|     where | ||||
|         Self: 'a, | ||||
|     { | ||||
|         Box::pin(async { | ||||
|             fa.await?; | ||||
|             Ok(b) | ||||
|         }) | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| impl<E> Pure for TryFutureClass<E> { | ||||
|     fn pure<'a, A: 'a>(a: A) -> Self::F<'a, A> | ||||
|     where | ||||
|         Self: 'a, | ||||
|     { | ||||
|         Box::pin(async { Ok(a) }) | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| impl<E> ApplicativeSeq for TryFutureClass<E> { | ||||
|     fn seq<'a, A: 'a, B: 'a>( | ||||
|         ff: Self::F<'a, impl 'a + FnOnce(A) -> B>, | ||||
|         fa: Self::F<'a, A>, | ||||
|     ) -> Self::F<'a, B> | ||||
|     where | ||||
|         Self: 'a, | ||||
|     { | ||||
|         Box::pin(async { | ||||
|             let (f, a) = try_join!(ff, fa)?; | ||||
|             Ok(f(a)) | ||||
|         }) | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| impl<E> ApplicativeLA2 for TryFutureClass<E> { | ||||
|     fn la2<'a, A: 'a, B: 'a, C: 'a>( | ||||
|         f: impl 'a + FnOnce(A, B) -> C, | ||||
|         fa: Self::F<'a, A>, | ||||
|         fb: Self::F<'a, B>, | ||||
|     ) -> Self::F<'a, C> | ||||
|     where | ||||
|         Self: 'a, | ||||
|     { | ||||
|         Box::pin(async { | ||||
|             let (a, b) = try_join!(fa, fb)?; | ||||
|             Ok(f(a, b)) | ||||
|         }) | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| impl<E> ApplicativeTuple for TryFutureClass<E> { | ||||
|     fn tuple<'a, A: 'a, B: 'a>((fa, fb): (Self::F<'a, A>, Self::F<'a, B>)) -> Self::F<'a, (A, B)> | ||||
|     where | ||||
|         Self: 'a, | ||||
|     { | ||||
|         Box::pin(async { try_join!(fa, fb) }) | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| impl<E> Applicative for TryFutureClass<E> { | ||||
|     fn discard_first<'a, A: 'a, B: 'a>(fa: Self::F<'a, A>, fb: Self::F<'a, B>) -> Self::F<'a, B> | ||||
|     where | ||||
|         Self: 'a, | ||||
|     { | ||||
|         Box::pin(async { Ok(try_join!(fa, fb)?.1) }) | ||||
|     } | ||||
| 
 | ||||
|     fn discard_second<'a, A: 'a, B: 'a>(fa: Self::F<'a, A>, fb: Self::F<'a, B>) -> Self::F<'a, A> | ||||
|     where | ||||
|         Self: 'a, | ||||
|     { | ||||
|         Box::pin(async { Ok(try_join!(fa, fb)?.0) }) | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| impl<E> Monad for TryFutureClass<E> { | ||||
|     fn bind<'a, A: 'a, B: 'a>( | ||||
|         fa: Self::F<'a, A>, | ||||
|         f: impl 'a + FnOnce(A) -> Self::F<'a, B>, | ||||
|     ) -> Self::F<'a, B> | ||||
|     where | ||||
|         Self: 'a, | ||||
|     { | ||||
|         Box::pin(async { f(fa.await?).await }) | ||||
|     } | ||||
| 
 | ||||
|     fn iterate_mut<'a, A: 'a, B: 'a>( | ||||
|         mut a: A, | ||||
|         mut f: impl 'a + FnMut(A) -> Self::F<'a, ControlFlow<B, A>>, | ||||
|     ) -> Self::F<'a, B> | ||||
|     where | ||||
|         Self: 'a, | ||||
|     { | ||||
|         Box::pin(async move { | ||||
|             loop { | ||||
|                 match f(a).await? { | ||||
|                     ControlFlow::Continue(next_a) => a = next_a, | ||||
|                     ControlFlow::Break(b) => return Ok(b), | ||||
|                 }; | ||||
|             } | ||||
|         }) | ||||
|     } | ||||
| 
 | ||||
|     fn iterate_argument<'a, A: 'a, B: 'a>( | ||||
|         mut a: A, | ||||
|         mut f: impl AIterative<'a, T = Self, A = A, B = B>, | ||||
|     ) -> Self::F<'a, B> | ||||
|     where | ||||
|         Self: 'a, | ||||
|     { | ||||
|         Box::pin(async move { | ||||
|             loop { | ||||
|                 match f.next(a).await? { | ||||
|                     ControlFlow::Continue((next_a, next_f)) => (a, f) = (next_a, next_f), | ||||
|                     ControlFlow::Break(b) => return Ok(b), | ||||
|                 } | ||||
|             } | ||||
|         }) | ||||
|     } | ||||
| 
 | ||||
|     fn iterate<'a, B: 'a>(mut f: impl Iterative<'a, T = Self, B = B>) -> Self::F<'a, B> | ||||
|     where | ||||
|         Self: 'a, | ||||
|     { | ||||
|         Box::pin(async move { | ||||
|             loop { | ||||
|                 match f.next().await? { | ||||
|                     ControlFlow::Continue(next_f) => f = next_f, | ||||
|                     ControlFlow::Break(b) => return Ok(b), | ||||
|                 } | ||||
|             } | ||||
|         }) | ||||
|     } | ||||
| 
 | ||||
|     fn join<'a, A: 'a>(ffa: Self::F<'a, Self::F<'a, A>>) -> Self::F<'a, A> | ||||
|     where | ||||
|         Self: 'a, | ||||
|     { | ||||
|         Box::pin(async { ffa.await?.await }) | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| impl<E: Clone> SharedFunctor for TryFutureClass<E> { | ||||
|     type Shared<'a, A: 'a + Clone> = Shared<Pin<Box<dyn 'a + Future<Output = Result<A, E>>>>> | ||||
|     where | ||||
|         Self: 'a; | ||||
| 
 | ||||
|     fn share<'a, A: 'a + Clone>(fa: Self::F<'a, A>) -> Self::Shared<'a, A> | ||||
|     where | ||||
|         Self: 'a, | ||||
|     { | ||||
|         fa.shared() | ||||
|     } | ||||
| 
 | ||||
|     fn unshare<'a, A: 'a + Clone>(sa: Self::Shared<'a, A>) -> Self::F<'a, A> | ||||
|     where | ||||
|         Self: 'a, | ||||
|     { | ||||
|         Box::pin(sa) | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| impl<E> MonadFail<E> for TryFutureClass<E> { | ||||
|     fn fail<'a, A: 'a>(e: E) -> Self::F<'a, A> | ||||
|     where | ||||
|         Self: 'a, | ||||
|         E: 'a, | ||||
|     { | ||||
|         Box::pin(async { Err(e) }) | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| struct FutureFailAny; | ||||
| 
 | ||||
| impl MonadFailAny for FutureFailAny { | ||||
|     type W<E> = TryFutureClass<E>; | ||||
| 
 | ||||
|     fn map_err<'a, A: 'a, E0: 'a, E1: 'a>( | ||||
|         wa: <Self::W<E0> as WeakFunctor>::F<'a, A>, | ||||
|         f: impl 'a + FnOnce(E0) -> E1, | ||||
|     ) -> <Self::W<E1> as WeakFunctor>::F<'a, A> | ||||
|     where | ||||
|         Self: 'a, | ||||
|     { | ||||
|         Box::pin(async { wa.await.map_err(f) }) | ||||
|     } | ||||
| 
 | ||||
|     fn bind_err<'a, A: 'a, E0: 'a, E1: 'a>( | ||||
|         wa: <Self::W<E0> as WeakFunctor>::F<'a, A>, | ||||
|         f: impl 'a + FnOnce(E0) -> <Self::W<E1> as WeakFunctor>::F<'a, A>, | ||||
|     ) -> <Self::W<E1> as WeakFunctor>::F<'a, A> | ||||
|     where | ||||
|         Self: 'a, | ||||
|     { | ||||
|         Box::pin(async { | ||||
|             match wa.await { | ||||
|                 Ok(a) => Ok(a), | ||||
|                 Err(e) => f(e).await, | ||||
|             } | ||||
|         }) | ||||
|     } | ||||
| 
 | ||||
|     fn rotate_out<'a, A: 'a, E0: 'a, E1: 'a>( | ||||
|         wa: <Self::W<E0> as WeakFunctor>::F<'a, Result<A, E1>>, | ||||
|     ) -> <Self::W<Result<E1, E0>> as WeakFunctor>::F<'a, A> | ||||
|     where | ||||
|         Self: 'a, | ||||
|     { | ||||
|         Box::pin(async { | ||||
|             match wa.await { | ||||
|                 Ok(Ok(a)) => Ok(a), | ||||
|                 Ok(Err(e)) => Err(Ok(e)), | ||||
|                 Err(e) => Err(Err(e)), | ||||
|             } | ||||
|         }) | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| impl MonadFailOver<classes::future::FutureClass> for FutureFailAny { | ||||
|     fn unstuff<'a, A: 'a, E: 'a>( | ||||
|         wa: <Self::W<E> as WeakFunctor>::F<'a, A>, | ||||
|     ) -> <classes::future::FutureClass as WeakFunctor>::F<'a, Result<A, E>> | ||||
|     where | ||||
|         Self: 'a, | ||||
|         classes::future::FutureClass: 'a, | ||||
|     { | ||||
|         wa | ||||
|     } | ||||
| 
 | ||||
|     fn stuff<'a, A: 'a, E: 'a>( | ||||
|         fa: <classes::future::FutureClass as WeakFunctor>::F<'a, Result<A, E>>, | ||||
|     ) -> <Self::W<E> as WeakFunctor>::F<'a, A> | ||||
|     where | ||||
|         Self: 'a, | ||||
|         classes::future::FutureClass: 'a, | ||||
|     { | ||||
|         fa | ||||
|     } | ||||
| } | ||||
		Loading…
	
		Reference in New Issue
	
	Block a user