Diffstat (limited to 'src/effect.rs')
-rw-r--r--src/effect.rs364
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 {