Diffstat (limited to 'src/effect.rs')
| -rw-r--r-- | src/effect.rs | 364 |
1 files changed, 341 insertions, 23 deletions
diff --git a/src/effect.rs b/src/effect.rs index 9207441..dea709c 100644 --- a/src/effect.rs +++ b/src/effect.rs @@ -1,6 +1,7 @@ use core::{ future::Future, marker::PhantomData, + ops::ControlFlow, pin::{pin, Pin}, ptr, task::{Context, Poll, RawWaker, RawWakerVTable, Waker}, @@ -54,6 +55,37 @@ pub trait Adapters<'lt>: Into<ObjSafe<'lt, Self::T, Self::Effect>> + 'lt { where F: FnOnce(Self::T) -> R, 'lt: 'a; + + type AsCtxFor: HktFn<Self::Effect> + HktFnOwn<Self::Effect> + HktFnMut<Self::Effect>; + + fn as_ctx_for<'ctx, 'a, R: 'a, F: 'a>(self, f: F) -> ObjSafe<'a, (Self::T, R), Self::Effect> + where + F: for<'b> FnOnce( + &'b mut Self::T, + PhantomData<&'b &'ctx ()>, + ) -> (ObjSafe<'b, R, Self::Effect>, PhantomData<&'b &'ctx ()>); + + fn then<'ctx, 'a, R: 'a, F: 'a>( + self, + f: F, + ) -> <<Self::AsCtxFor as HktFnOwn<Self::Effect>>::T<Self::T, R, F, &'ctx ()> as ForLtFnOwn< + 'a, + Self::T, + R, + F, + &'a (Self::T, R, F, &'ctx ()), + &'ctx (), + Self::Effect, + >>::T + where + F: for<'b> FnOnce( + Self::T, + PhantomData<&'b &'ctx ()>, + ) -> ObjSafe<'b, R, Self::Effect>; + + fn r#loop<'ctx, 'a, R: 'a, F: 'a>(self, f: F) -> ObjSafe<'a, R, Self::Effect> + where + F: for<'b> FnMut(&'b mut Self::T) -> ObjSafe<'b, ControlFlow<R>, Self::Effect>; } pub trait ForLt<'a, Output: 'a, B> { @@ -68,11 +100,75 @@ pub trait Hkt { type T<Output, B>: for<'a> ForLt<'a, Output, &'a (Output, B), Effect = Self::Effect>; } -pub trait ForLtFn<'a, E: Effect> { - type T<Input: 'a, Output: 'a, F: 'a + for<'b> FnOnce(&'b mut Input) -> ObjSafe<'b, Output, E>>: Adapters<'a, Effect = E, T = Output>; +pub trait ForLtFn<'a, Input: 'a, Output: 'a, F: 'a, B, O, E: Effect> +where + F: for<'b> FnOnce( + &'b mut Input, + PhantomData<&'b O>, + ) -> (ObjSafe<'b, Output, E>, PhantomData<&'b O>), +{ + type T: Adapters<'a, Effect = E, T = Output>; +} + +pub trait HktFn<E: Effect> { + type T<Input, Output, F: for<'b> FnOnce(&'b mut Input, PhantomData<&'b B>) -> (ObjSafe<'b, Output, E>, PhantomData<&'b B>), B>: for<'a> ForLtFn<'a, Input, Output, F, &'a (Input, Output, F, B), B, E>; +} + +impl<'b, T, Input: 'b, Output: 'b, ForBound, E: Effect> MutMapFnMut<'b, Input, Output, ForBound, E> + for T +where + T: FnMut(&'b mut Input) -> ObjSafe<'b, Output, E>, +{ + fn call(&mut self, input: &'b mut Input) -> ObjSafe<'b, Output, E> { + self(input) + } +} + +pub trait MutMapFnMut<'b, FIn: 'b, FOut: 'b, ForBound, E: Effect> { + fn call(&mut self, input: &'b mut FIn) -> ObjSafe<'b, FOut, E>; +} + +pub trait ForLtFnMut<'a, FIn: 'a, FOut, Output: 'a, F: 'a, ForBound, E: Effect> +where + for<'b> F: MutMapFnMut<'b, FIn, FOut, &'b (FIn, FOut), E>, +{ + type T: Adapters<'a, Effect = E, T = Output>; +} + +// pub trait ForLtFnMut<'a, Input: 'a, Output: 'a, F: 'a, B, O, E: Effect> +// where +// F: for<'b> FnMut( +// &'b mut Input, +// PhantomData<&'b O>, +// ) -> (ObjSafe<'b, Output, E>, PhantomData<&'b O>), +// { +// type T: Adapters<'a, Effect = E, T = Output>; +// } + +pub trait HktFnMut<E: Effect> { + type T<FIn, FOut, Output, F: for<'b> MutMapFnMut<'b, FIn, FOut, &'b (FIn, FOut), E>, ForBound>: for<'a> ForLtFnMut<'a, FIn, FOut, Output, F, &'a (FIn, Output, F, ForBound), E>; } -pub trait HktFn<E: Effect>: for<'a> ForLtFn<'a, E> {} +// pub trait HktFnMut<E: Effect> { +// type T<Input, Output, F: for<'b> FnMut(&'b mut Input, PhantomData<&'b B>) -> (ObjSafe<'b, Output, E>, PhantomData<&'b B>), B>: for<'a> ForLtFnMut<'a, Input, Output, F, &'a (Input, Output, F, B), B, E>; +// } + +pub trait ForLtFnOwn<'a, Input: 'a, Output: 'a, F: 'a, B, O, E: Effect> +where + F: for<'b> FnOnce(Input, PhantomData<&'b O>) -> ObjSafe<'b, Output, E>, +{ + type T: Adapters<'a, Effect = E, T = Output>; +} + +pub trait HktFnOwn<E: Effect> { + type T<Input, Output, F: for<'b> FnOnce(Input, PhantomData<&'b B>) -> ObjSafe<'b, Output, E>, B>: for<'a> ForLtFnOwn<'a, Input, Output, F, &'a (Input, Output, F, B),B, E>; +} + +// pub trait ForLtFn<'a, E: Effect> { +// type T<Input: 'a, Output: 'a, F: 'a + for<'b> FnOnce(&'b mut Input) -> ObjSafe<'b, Output, E>>: Adapters<'a, Effect = E, T = Output>; +// } +// +// pub trait HktFn<E: Effect>: for<'a> ForLtFn<'a, E> {} /// Trait for effects. pub trait Effect: Sized + Send + Sync + 'static { @@ -84,13 +180,105 @@ pub trait Effect: Sized + Send + Sync + 'static { type With: HktFn<Self>; - fn with<'a, T: 'a, R: 'a, F: 'a>(x: T, f: F) -> <Self::With as ForLtFn<'a, Self>>::T<T, R, F> + fn with<'ctx, 'a, T: 'a, R: 'a, F: 'a>( + x: T, + f: F, + ) -> <<Self::With as HktFn<Self>>::T<T, R, F, &'ctx ()> as ForLtFn< + 'a, + T, + R, + F, + &'a (T, R, F, &'ctx ()), + &'ctx (), + Self, + >>::T where - F: FnOnce(&mut T) -> ObjSafe<'_, R, Self>; + F: for<'b> FnOnce( + &'b mut T, + PhantomData<&'b &'ctx ()>, + ) -> (ObjSafe<'b, R, Self>, PhantomData<&'b &'ctx ()>); + + fn join<'a, T: 'a>(tuple: T) -> ObjSafe<'a, T::Output, Self> + where + T: Joinable<'a, Self>, + { + T::join(tuple) + } + + fn try_join<'a, T: 'a>(tuple: T) -> ObjSafe<'a, Result<T::Output, T::Error>, Self> + where + T: TryJoinable<'a, Self>, + { + T::try_join(tuple) + } +} + +pub trait Joinable<'a, E: Effect>: Sized { + type Output; + + fn join(tuple: Self) -> ObjSafe<'a, Self::Output, E>; } -pub type ObjSafe<'a, T, E> = - <<<E as Effect>::ObjSafe as Hkt>::T<T, ()> as ForLt<'a, T, &'a (T, ())>>::T; +pub struct Join<T, B>(pub T, pub Marker<B>); + +impl<'a, E: Effect, T0> Joinable<'a, E> for Join<(ObjSafe<'a, T0, E>,), (T0,)> { + fn join(Join((a,), _): Self) -> ObjSafe<'a, (T0,), E> { + a.map(|x| (x,)).into() + } + + type Output = (T0,); +} + +impl<'a, E: Effect, T0, T1> Joinable<'a, E> + for Join<(ObjSafe<'a, T0, E>, ObjSafe<'a, T1, E>), (T0, T1)> +{ + fn join(Join((a, b), _): Self) -> ObjSafe<'a, (T0, T1), E> { + a.then(|a, _| b.map(|b| (a, b)).into()).into() + } + + type Output = (T0, T1); +} + +pub trait TryJoinable<'a, E: Effect>: Sized { + type Output; + + type Error; + + fn try_join(tuple: Self) -> ObjSafe<'a, Result<Self::Output, Self::Error>, E>; +} + +impl<'a, E: Effect, Err, T0, T1> TryJoinable<'a, E> + for Join< + ( + ObjSafe<'a, Result<T0, Err>, E>, + ObjSafe<'a, Result<T1, Err>, E>, + ), + (Err, T0, T1), + > +{ + fn try_join(Join((a, b), _): Self) -> ObjSafe<'a, Result<(T0, T1), Err>, E> { + a.then(|a, _| { + match a { + Ok(a) => b + .map(|b| match b { + Ok(b) => Ok((a, b)), + Err(err) => Err(err), + }) + .into(), + Err(err) => E::ready(Err(err)).into(), + } + // b.map(|b| (a, b)).into() + }) + .into() + } + + type Output = (T0, T1); + + type Error = Err; +} + +pub type ObjSafe<'a, T, E, B = ()> = + <<<E as Effect>::ObjSafe as Hkt>::T<T, B> as ForLt<'a, T, &'a (T, B)>>::T; pub enum Blocking {} @@ -112,14 +300,62 @@ impl<'a, T, B> ForLt<'a, T, &'a (T, B)> for ValueHrt<T, B> { pub enum WithHkt {} -impl HktFn<Blocking> for WithHkt {} +impl HktFnOwn<Blocking> for WithHkt { + type T< + Input, + Output, + F: for<'b> FnOnce(Input, PhantomData<&'b B>) -> ObjSafe<'b, Output, Blocking>, + B, + > = WithHkt; +} -impl<'a> ForLtFn<'a, Blocking> for WithHkt { +impl<'a, Input, Output, F, B> + ForLtFnOwn<'a, Input, Output, F, &'a (Input, Output, F, B), B, Blocking> for WithHkt +where + F: for<'b> FnOnce(Input, PhantomData<&'b B>) -> ObjSafe<'b, Output, Blocking>, +{ + type T = Value<Output>; +} + +impl HktFn<Blocking> for WithHkt { type T< - Input: 'a, - Output: 'a, - F: 'a + for<'b> FnOnce(&'b mut Input) -> ObjSafe<'b, Output, Blocking>, - > = Value<Output>; + Input, + Output, + F: for<'b> FnOnce( + &'b mut Input, + PhantomData<&'b B>, + ) -> (ObjSafe<'b, Output, Blocking>, PhantomData<&'b B>), + B, + > = WithHkt; +} + +impl<'a, Input, Output, F, B> ForLtFn<'a, Input, Output, F, &'a (Input, Output, F, B), B, Blocking> + for WithHkt +where + F: for<'b> FnOnce( + &'b mut Input, + PhantomData<&'b B>, + ) -> (ObjSafe<'b, Output, Blocking>, PhantomData<&'b B>), +{ + type T = Value<Output>; +} + +impl HktFnMut<Blocking> for WithHkt { + type T< + FIn, + FOut, + Output, + F: for<'b> MutMapFnMut<'b, FIn, FOut, &'b (FIn, FOut), Blocking>, + ForBound, + > = WithHkt; +} + +impl<'a, FIn, FOut, Output, F, B> + ForLtFnMut<'a, FIn, FOut, Output, F, &'a (FIn, Output, F, B), Blocking> for WithHkt +where + for<'b> F: MutMapFnMut<'b, FIn, FOut, &'b (FIn, FOut), Blocking>, +{ + type T = Value<Output>; } impl Effect for Blocking { @@ -133,12 +369,27 @@ impl Effect for Blocking { type With = WithHkt; - fn with<'a, T: 'a, R: 'a, F: 'a>(x: T, f: F) -> <Self::With as ForLtFn<'a, Blocking>>::T<T, R, F> + #[inline(always)] + fn with<'ctx, 'a, T: 'a, R: 'a, F: 'a>( + x: T, + f: F, + ) -> <<Self::With as HktFn<Self>>::T<T, R, F, &'ctx ()> as ForLtFn< + 'a, + T, + R, + F, + &'a (T, R, F, &'ctx ()), + &'ctx (), + Self, + >>::T where - F: FnOnce(&mut T) -> ObjSafe<'_, R, Self>, + F: for<'b> FnOnce( + &'b mut T, + PhantomData<&'b &'ctx ()>, + ) -> (ObjSafe<'b, R, Self>, PhantomData<&'b &'ctx ()>), { let mut ctx = x; - f(&mut ctx) + f(&mut ctx, PhantomData).0 } } @@ -158,8 +409,56 @@ impl<'b, U: 'b> Adapters<'b> for Value<U> { { Value(f(self.0)) } + + type AsCtxFor = WithHkt; + + #[inline(always)] + fn as_ctx_for<'ctx, 'a, R: 'a, F: 'a>(self, f: F) -> ObjSafe<'a, (Self::T, R), Blocking> + where + F: for<'c> FnOnce( + &'c mut Self::T, + PhantomData<&'c &'ctx ()>, + ) -> (ObjSafe<'c, R, Self::Effect>, PhantomData<&'c &'ctx ()>), + { + let mut ctx = self.0; + let value = f(&mut ctx, PhantomData).0 .0; + Value((ctx, value)) + } + + fn then<'ctx, 'a, R: 'a, F: 'a>( + self, + f: F, + ) -> <<Self::AsCtxFor as HktFnOwn<Self::Effect>>::T<Self::T, R, F, &'ctx ()> as ForLtFnOwn< + 'a, + Self::T, + R, + F, + &'a (Self::T, R, F, &'ctx ()), + &'ctx (), + Self::Effect, + >>::T + where + F: for<'c> FnOnce( + Self::T, + PhantomData<&'c &'ctx ()>, + ) -> ObjSafe<'c, R, Self::Effect>{ + f(self.0, PhantomData) + } + + #[inline(always)] + fn r#loop<'ctx, 'a, R: 'a, F: 'a>(mut self, mut f: F) -> ObjSafe<'a, R, Blocking> + where + F: for<'c> FnMut(&'c mut Self::T) -> ObjSafe<'c, ControlFlow<R>, Self::Effect>, + { + loop { + if let ControlFlow::Break(value) = f(&mut self.0).0 { + return Value(value); + } + } + } } +/* pub enum Async {} impl Effect for Async { @@ -173,9 +472,20 @@ impl Effect for Async { type With = AsyncWithHkt; - fn with<'a, T: 'a, R: 'a, F: 'a>(x: T, f: F) -> <Self::With as ForLtFn<'a, Self>>::T<T, R, F> + fn with<'a, T: 'a, R: 'a, F: 'a>( + x: T, + f: F, + ) -> <<Self::With as HktFn<Self>>::T<T, R, F, ()> as ForLtFn< + 'a, + T, + R, + F, + &'a (T, R, F, ()), + Self, + >>::T where - F: FnOnce(&mut T) -> ObjSafe<'_, R, Self> { + F: FnOnce(&mut T) -> ObjSafe<'_, R, Self>, + { BoxedFuture(Box::pin(async move { let mut x = x; @@ -211,10 +521,17 @@ impl Hkt for AsyncValueHkt { pub enum AsyncWithHkt {} -impl HktFn<Async> for AsyncWithHkt {} +impl HktFn<Async> for AsyncWithHkt { + type T<Input, Output, F: for<'b> FnOnce(&'b mut Input) -> ObjSafe<'b, Output, Async>, B> = + AsyncWithHkt; +} -impl<'a> ForLtFn<'a, Async> for AsyncWithHkt { - type T<Input: 'a, Output: 'a, F: 'a + for<'b> FnOnce(&'b mut Input) -> ObjSafe<'b, Output, Async>> = BoxedFuture<'a, Output>; +impl<'a, Input, Output, F, B> ForLtFn<'a, Input, Output, F, &'a (Input, Output, F, B), Async> + for AsyncWithHkt +where + F: for<'b> FnOnce(&'b mut Input) -> ObjSafe<'b, Output, Async>, +{ + type T = BoxedFuture<'a, Output>; } pub struct AsyncValue<T>(pub T); @@ -256,7 +573,7 @@ impl<'b, U: 'b> Adapters<'b> for BoxedFuture<'b, U> { 'b: 'a, { AsyncMap { - map: futures::FutureExt::map(self, f) + map: futures::FutureExt::map(self, f), } } } @@ -284,7 +601,7 @@ where 'b: 'a, { AsyncMap { - map: futures::FutureExt::map(self, f) + map: futures::FutureExt::map(self, f), } } } @@ -325,6 +642,7 @@ impl<'a, T: 'a> From<AsyncValue<T>> for BoxedFuture<'a, T> { BoxedFuture(Box::pin(futures::future::ready(value.0))) } } +*/ /* pub trait ReadyValue: core::future::Future { |