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