Diffstat (limited to 'src/effect.rs')
-rw-r--r--src/effect.rs145
1 files changed, 120 insertions, 25 deletions
diff --git a/src/effect.rs b/src/effect.rs
index b0203bc..9207441 100644
--- a/src/effect.rs
+++ b/src/effect.rs
@@ -39,10 +39,10 @@ use crate::{higher_ranked_trait, higher_ranked_type, hkt::Marker};
// }
// pub mod Effective {
-//
+//
// }
//
-pub trait Adapters<'lt>: Into<<Self::Effect as Effect>::ObjSafe<'lt, Self::T>> + 'lt {
+pub trait Adapters<'lt>: Into<ObjSafe<'lt, Self::T, Self::Effect>> + 'lt {
type Effect: Effect;
type T: 'lt;
@@ -56,43 +56,89 @@ pub trait Adapters<'lt>: Into<<Self::Effect as Effect>::ObjSafe<'lt, Self::T>> +
'lt: 'a;
}
+pub trait ForLt<'a, Output: 'a, B> {
+ type Effect: Effect;
+
+ type T: Adapters<'a, Effect = Self::Effect, T = Output>;
+}
+
+pub trait Hkt {
+ type Effect: Effect;
+
+ 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 HktFn<E: Effect>: for<'a> ForLtFn<'a, E> {}
+
/// Trait for effects.
pub trait Effect: Sized + Send + Sync + 'static {
- type ObjSafe<'a, T: 'a>: Adapters<'a, Effect = Self, T = T>;
+ type ObjSafe: Hkt<Effect = Self>;
- type Ready<'a, T: 'a>: Adapters<'a, Effect = Self, T = T>;
+ type Ready: Hkt<Effect = Self>;
- fn ready<'a, T: 'a>(x: T) -> Self::Ready<'a, T>;
+ fn ready<'a, T: 'a>(x: T) -> <<Self::Ready as Hkt>::T<T, ()> as ForLt<'a, T, &'a (T, ())>>::T;
- type With<'a, T: 'a, R: 'a, F: 'a + FnOnce(&mut T) -> R>: Adapters<'a, Effect = Self, T = R>;
+ type With: HktFn<Self>;
- fn with<'a, T: 'a, R: 'a, F: 'a>(x: T, f: F) -> Self::With<'a, T, R::T, F>
- where
- R: Adapters<'a, Effect = Self>,
- F: FnOnce(&mut T) -> R;
+ fn with<'a, T: 'a, R: 'a, F: 'a>(x: T, f: F) -> <Self::With as ForLtFn<'a, Self>>::T<T, R, F>
+ where
+ F: FnOnce(&mut T) -> ObjSafe<'_, R, Self>;
}
-pub type ObjSafe<'a, T, E> = <E as Effect>::ObjSafe<'a, T>;
+pub type ObjSafe<'a, T, E> =
+ <<<E as Effect>::ObjSafe as Hkt>::T<T, ()> as ForLt<'a, T, &'a (T, ())>>::T;
pub enum Blocking {}
+pub enum ValueHkt {}
+
+impl Hkt for ValueHkt {
+ type Effect = Blocking;
+
+ type T<Output, B> = ValueHrt<Output, B>;
+}
+
+pub struct ValueHrt<T, B>(Marker<(T, B)>);
+
+impl<'a, T, B> ForLt<'a, T, &'a (T, B)> for ValueHrt<T, B> {
+ type Effect = Blocking;
+
+ type T = Value<T>;
+}
+
+pub enum WithHkt {}
+
+impl HktFn<Blocking> for WithHkt {}
+
+impl<'a> ForLtFn<'a, Blocking> for WithHkt {
+ type T<
+ Input: 'a,
+ Output: 'a,
+ F: 'a + for<'b> FnOnce(&'b mut Input) -> ObjSafe<'b, Output, Blocking>,
+ > = Value<Output>;
+}
+
impl Effect for Blocking {
- type ObjSafe<'a, T: 'a> = Value<T>;
+ type ObjSafe = ValueHkt;
- type Ready<'a, T: 'a> = Value<T>;
+ type Ready = ValueHkt;
- fn ready<'a, T: 'a>(x: T) -> Self::Ready<'a, T> {
+ fn ready<'a, T: 'a>(x: T) -> <<Self::Ready as Hkt>::T<T, ()> as ForLt<'a, T, &'a (T, ())>>::T {
Value(x)
}
- type With<'a, T: 'a, R: 'a, F: 'a + FnOnce(&mut T) -> R> = Value<R>;
+ type With = WithHkt;
- fn with<'a, T: 'a, R: 'a, F: 'a>(x: T, f: F) -> Self::With<'a, T, R::T, F>
- where
- R: Adapters<'a, Effect = Self>,
- F: FnOnce(&mut T) -> R {
+ fn with<'a, T: 'a, R: 'a, F: 'a>(x: T, f: F) -> <Self::With as ForLtFn<'a, Blocking>>::T<T, R, F>
+ where
+ F: FnOnce(&mut T) -> ObjSafe<'_, R, Self>,
+ {
let mut ctx = x;
- Value(f(&mut ctx))
+ f(&mut ctx)
}
}
@@ -114,21 +160,71 @@ impl<'b, U: 'b> Adapters<'b> for Value<U> {
}
}
-/*
pub enum Async {}
impl Effect for Async {
- type ObjSafe<'a, T: 'a> = BoxedFuture<'a, T>;
+ type ObjSafe = BoxedFutureHkt;
- type Ready<'a, T: 'a> = AsyncValue<T>;
+ type Ready = AsyncValueHkt;
- fn ready<'a, T: 'a>(x: T) -> Self::Ready<'a, T> {
+ fn ready<'a, T: 'a>(x: T) -> <<Self::Ready as Hkt>::T<T, ()> as ForLt<'a, T, &'a (T, ())>>::T {
AsyncValue(x)
}
+
+ 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>
+ where
+ F: FnOnce(&mut T) -> ObjSafe<'_, R, Self> {
+ BoxedFuture(Box::pin(async move {
+ let mut x = x;
+
+ let fut = f(&mut x).0;
+ fut.await
+ }))
+ }
+}
+
+pub enum BoxedFutureHkt {}
+
+impl Hkt for BoxedFutureHkt {
+ type Effect = Async;
+
+ type T<Output, B> = BoxedFutureHrt<Output, B>;
+}
+
+pub struct BoxedFutureHrt<Output, B>(Marker<(Output, B)>);
+
+impl<'a, Output, B> ForLt<'a, Output, &'a (Output, B)> for BoxedFutureHrt<Output, B> {
+ type Effect = Async;
+
+ type T = BoxedFuture<'a, Output>;
+}
+
+pub enum AsyncValueHkt {}
+
+impl Hkt for AsyncValueHkt {
+ type Effect = Async;
+
+ type T<Output, B> = AsyncValue<Output>;
+}
+
+pub enum AsyncWithHkt {}
+
+impl HktFn<Async> for 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>;
}
pub struct AsyncValue<T>(pub T);
+impl<'a, T, B> ForLt<'a, T, &'a (T, B)> for AsyncValue<T> {
+ type Effect = Async;
+
+ type T = AsyncValue<T>;
+}
+
pub struct BoxedFuture<'a, T: 'a>(pub Pin<Box<dyn Future<Output = T> + 'a>>);
impl<'b, U: 'b> Adapters<'b> for AsyncValue<U> {
@@ -229,7 +325,6 @@ 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 {