From f82020f766bd1874862223a2492499851e5dcaf2 Mon Sep 17 00:00:00 2001 From: timofey Date: Fri, 17 Mar 2023 09:26:56 +0000 Subject: [PATCH] CompositionClass + two RCs --- src/core.rs | 53 +++++++++++---------------- src/func.rs | 53 +++++++++++++++++++-------- src/func/classes.rs | 1 + src/func/classes/compositionclass.rs | 55 ++++++++++++++++++++++++++++ src/func/classes/futureclass.rs | 4 -- src/func/classes/lazyclass.rs | 4 -- src/func/classes/optionclass.rs | 4 -- src/func/classes/resultclass.rs | 4 -- src/func/classes/soloclass.rs | 4 -- src/func/tests.rs | 26 ++++++------- 10 files changed, 129 insertions(+), 79 deletions(-) create mode 100644 src/func/classes/compositionclass.rs diff --git a/src/core.rs b/src/core.rs index 2c3c596..6a4ccd9 100644 --- a/src/core.rs +++ b/src/core.rs @@ -1,3 +1,5 @@ +use std::{rc::Rc, error::Error}; + use crate::func::*; pub trait Context { @@ -34,17 +36,18 @@ pub trait Deserializer { pub trait Factory: Clone { type Mtbl: Mentionable; + type ParseError: Error; - fn deserialize(&self, deserializer: F) -> Self::Mtbl; + fn deserialize(&self, deserializer: F) -> Result; } pub trait Origin<'a, Ctx: Context>: 'a { type Mtbl: Mentionable; fn factory(&self) -> >::Fctr; - fn resolve(self: Box) -> <::T as WeakFunctor>::F<'a, Self::Mtbl>; + fn resolve(&self) -> <::T as WeakFunctor>::F<'a, Rc>; } -struct LocalOrigin(A); +struct LocalOrigin(Rc); impl<'a, Ctx: 'a + Context, A: 'a + Mentionable> Origin<'a, Ctx> for LocalOrigin { type Mtbl = A; @@ -53,60 +56,48 @@ impl<'a, Ctx: 'a + Context, A: 'a + Mentionable> Origin<'a, Ctx> for LocalO self.0.factory() } - fn resolve(self: Box) -> <::T as WeakFunctor>::F<'a, Self::Mtbl> { - ::pure(self.0) + fn resolve(&self) -> <::T as WeakFunctor>::F<'a, Rc> { + ::pure(self.0.clone()) } } -struct ApplicativeOrigin<'a, Ctx: Context, A: Mentionable>( - <::T as WeakFunctor>::F<'a, A>, - A::Fctr, -); - -impl<'a, Ctx: 'a + Context, A: 'a + Mentionable> Origin<'a, Ctx> - for ApplicativeOrigin<'a, Ctx, A> -{ - type Mtbl = A; - - fn factory(&self) -> >::Fctr { - self.1.clone() - } - - fn resolve(self: Box) -> <::T as WeakFunctor>::F<'a, Self::Mtbl> { - self.0 +impl From for LocalOrigin { + fn from(value: A) -> Self { + LocalOrigin(value.into()) } } -pub struct HashPoint<'a, Ctx: Context, A: Mentionable> { - point: Hash, - origin: Box>, +#[derive(Clone)] +pub struct Point<'a, Ctx: Context, A: Mentionable> { + pub point: Hash, + pub origin: Rc>, } -impl<'a, Ctx: 'a + Context, A: 'a + Mentionable> HashPoint<'a, Ctx, A> { +impl<'a, Ctx: 'a + Context, A: 'a + Mentionable> Point<'a, Ctx, A> { fn prepare_bytes_for_hashing(mentioned: &A) -> Vec { let mut vec = mentioned.topology().to_vec(); mentioned.serialize(|x: &[u8]| vec.extend(x.iter())); vec } - fn from_fields(point: Hash, origin: Box>) -> Self { - HashPoint { point, origin } + fn from_fields(point: Hash, origin: Rc>) -> Self { + Point { point, origin } } fn from_values>(point: Hash, origin: O) -> Self { - Self::from_fields(point, Box::new(origin)) + Self::from_fields(point, Rc::new(origin)) } - fn resolve(self) -> <::T as WeakFunctor>::F<'a, A> { + pub fn resolve(&self) -> <::T as WeakFunctor>::F<'a, Rc> { self.origin.resolve() } } -impl<'a, Ctx: 'a + Context, A: 'a + Mentionable> From for HashPoint<'a, Ctx, A> { +impl<'a, Ctx: 'a + Context, A: 'a + Mentionable> From for Point<'a, Ctx, A> { fn from(value: A) -> Self { Self::from_values( Ctx::hash(Self::prepare_bytes_for_hashing(&value).as_slice()), - LocalOrigin(value), + LocalOrigin::from(value), ) } } diff --git a/src/func.rs b/src/func.rs index 2db603e..47c3533 100644 --- a/src/func.rs +++ b/src/func.rs @@ -7,11 +7,7 @@ pub mod test_suite; pub mod tests; pub trait WeakFunctor { - type F<'a, A>: CarriesType; -} - -pub trait CarriesType { - type A; + type F<'a, A>; } /// Rust-specific implementation of [Functor], respecting `move` semantics. @@ -55,13 +51,21 @@ pub trait CarriesType { /// ``` pub trait Functor: WeakFunctor { - fn fmap<'a, A: 'a, B: 'a, F: 'a + FnOnce(A) -> B>(f: F, fa: Self::F<'a, A>) -> Self::F<'a, B>; + fn fmap<'a, A: 'a, B: 'a, F: 'a + FnOnce(A) -> B>(f: F, fa: Self::F<'a, A>) -> Self::F<'a, B> + where + Self: 'a; - fn replace<'a, A: 'a, B: 'a>(fa: Self::F<'a, A>, b: B) -> Self::F<'a, B> { + fn replace<'a, A: 'a, B: 'a>(fa: Self::F<'a, A>, b: B) -> Self::F<'a, B> + where + Self: 'a, + { Self::fmap(|_| b, fa) } - fn void<'a, A: 'a>(fa: Self::F<'a, A>) -> Self::F<'a, ()> { + fn void<'a, A: 'a>(fa: Self::F<'a, A>) -> Self::F<'a, ()> + where + Self: 'a, + { Self::replace(fa, ()) } } @@ -70,12 +74,17 @@ pub trait ApplicativeSeq: Functor { fn seq<'a, A: 'a, B: 'a, F: 'a + FnOnce(A) -> B>( ff: Self::F<'a, F>, fa: Self::F<'a, A>, - ) -> Self::F<'a, B>; + ) -> Self::F<'a, B> + where + Self: 'a; fn _la2<'a, A: 'a, B: 'a, C: 'a, F: 'a + FnOnce(A, B) -> C>( f: F, fa: Self::F<'a, A>, fb: Self::F<'a, B>, - ) -> Self::F<'a, C> { + ) -> Self::F<'a, C> + where + Self: 'a, + { Self::seq(Self::fmap(|a| |b| f(a, b), fa), fb) } } @@ -85,11 +94,16 @@ pub trait ApplicativeLA2: Functor { f: F, fa: Self::F<'a, A>, fb: Self::F<'a, B>, - ) -> Self::F<'a, C>; + ) -> Self::F<'a, C> + where + Self: 'a; fn _seq<'a, A: 'a, B: 'a, F: 'a + FnOnce(A) -> B>( ff: Self::F<'a, F>, fa: Self::F<'a, A>, - ) -> Self::F<'a, B> { + ) -> Self::F<'a, B> + where + Self: 'a, + { Self::la2(|f, a| f(a), ff, fa) } } @@ -97,11 +111,17 @@ pub trait ApplicativeLA2: Functor { pub trait Applicative: Functor + ApplicativeSeq + ApplicativeLA2 { fn pure<'a, A: 'a>(a: A) -> Self::F<'a, A>; - fn discard_first<'a, A: 'a, B: 'a>(fa: Self::F<'a, A>, fb: Self::F<'a, B>) -> Self::F<'a, B> { + 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, + { Self::seq(Self::replace(fa, |b| b), fb) } - fn discard_second<'a, A: 'a, B: 'a>(fa: Self::F<'a, A>, fb: Self::F<'a, B>) -> Self::F<'a, A> { + 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, + { Self::la2(|a, _| a, fa, fb) } } @@ -110,11 +130,14 @@ pub trait Monad: Applicative { fn bind<'a, A: 'a, B: 'a, F: 'a + FnOnce(A) -> Self::F<'a, B>>( fa: Self::F<'a, A>, f: F, - ) -> Self::F<'a, B>; + ) -> Self::F<'a, B> + where + Self: 'a; fn join<'a, A: 'a>(ffa: Self::F<'a, Self::F<'a, A>>) -> Self::F<'a, A> where Self::F<'a, A>: 'a, + Self: 'a, { Self::bind(ffa, |fa| fa) } diff --git a/src/func/classes.rs b/src/func/classes.rs index 65a4526..a745fa3 100644 --- a/src/func/classes.rs +++ b/src/func/classes.rs @@ -1,3 +1,4 @@ +pub mod compositionclass; pub mod futureclass; pub mod lazyclass; pub mod optionclass; diff --git a/src/func/classes/compositionclass.rs b/src/func/classes/compositionclass.rs new file mode 100644 index 0000000..0539ff8 --- /dev/null +++ b/src/func/classes/compositionclass.rs @@ -0,0 +1,55 @@ +use crate::func::*; + +struct CompositionClass(U, V); + +impl WeakFunctor for CompositionClass { + type F<'a, A> = U::F<'a, V::F<'a, A>>; +} + +impl Functor for CompositionClass { + fn fmap<'a, A: 'a, B: 'a, F: 'a + FnOnce(A) -> B>(f: F, fa: Self::F<'a, A>) -> Self::F<'a, B> + where + Self: 'a, + { + U::fmap(|ua| V::fmap(f, ua), fa) + } + + fn replace<'a, A: 'a, B: 'a>(fa: Self::F<'a, A>, b: B) -> Self::F<'a, B> + where + Self: 'a, + { + U::fmap(|ua| V::replace(ua, b), fa) + } + + fn void<'a, A: 'a>(fa: Self::F<'a, A>) -> Self::F<'a, ()> + where + Self: 'a, + { + U::fmap(|ua| V::void(ua), fa) + } +} + +impl ApplicativeSeq for CompositionClass { + fn seq<'a, A: 'a, B: 'a, F: 'a + FnOnce(A) -> B>( + ff: Self::F<'a, F>, + fa: Self::F<'a, A>, + ) -> Self::F<'a, B> + where + Self: 'a, + { + U::la2(|uf, ua| V::seq(uf, ua), ff, fa) + } +} + +impl ApplicativeLA2 for CompositionClass { + fn la2<'a, A: 'a, B: 'a, C: 'a, F: 'a + FnOnce(A, B) -> C>( + f: F, + fa: Self::F<'a, A>, + fb: Self::F<'a, B>, + ) -> Self::F<'a, C> + where + Self: 'a, + { + U::la2(|ua, ub| V::la2(f, ua, ub), fa, fb) + } +} diff --git a/src/func/classes/futureclass.rs b/src/func/classes/futureclass.rs index ab99c12..c62c7d2 100644 --- a/src/func/classes/futureclass.rs +++ b/src/func/classes/futureclass.rs @@ -10,10 +10,6 @@ impl WeakFunctor for FutureClass { type F<'a, A> = Pin>>; } -impl<'a, A> CarriesType for Pin>> { - type A = A; -} - impl Functor for FutureClass { fn fmap<'a, A: 'a, B: 'a, F: 'a + FnOnce(A) -> B>(f: F, fa: Self::F<'a, A>) -> Self::F<'a, B> { Box::pin(async { f(fa.await) }) diff --git a/src/func/classes/lazyclass.rs b/src/func/classes/lazyclass.rs index 42cb370..f1ed914 100644 --- a/src/func/classes/lazyclass.rs +++ b/src/func/classes/lazyclass.rs @@ -6,10 +6,6 @@ impl WeakFunctor for LazyClass { type F<'a, A> = Box A>; } -impl<'a, A> CarriesType for Box A> { - type A = A; -} - impl Functor for LazyClass { fn fmap<'a, A: 'a, B: 'a, F: 'a + FnOnce(A) -> B>(f: F, fa: Self::F<'a, A>) -> Self::F<'a, B> { Box::new(|| f(fa())) diff --git a/src/func/classes/optionclass.rs b/src/func/classes/optionclass.rs index 85b16e0..c246b70 100644 --- a/src/func/classes/optionclass.rs +++ b/src/func/classes/optionclass.rs @@ -6,10 +6,6 @@ impl WeakFunctor for OptionClass { type F<'a, A> = Option; } -impl CarriesType for Option { - type A = A; -} - impl Functor for OptionClass { fn fmap<'a, A: 'a, B: 'a, F: 'a + FnOnce(A) -> B>(f: F, fa: Self::F<'a, A>) -> Self::F<'a, B> { fa.map(f) diff --git a/src/func/classes/resultclass.rs b/src/func/classes/resultclass.rs index 8b6db3f..e59715f 100644 --- a/src/func/classes/resultclass.rs +++ b/src/func/classes/resultclass.rs @@ -6,10 +6,6 @@ impl WeakFunctor for ResultClass { type F<'a, A> = Result; } -impl CarriesType> for Result { - type A = A; -} - impl Functor for ResultClass { fn fmap<'a, A: 'a, B: 'a, F: 'a + FnOnce(A) -> B>(f: F, fa: Self::F<'a, A>) -> Self::F<'a, B> { fa.map(f) diff --git a/src/func/classes/soloclass.rs b/src/func/classes/soloclass.rs index c063beb..f04d3e0 100644 --- a/src/func/classes/soloclass.rs +++ b/src/func/classes/soloclass.rs @@ -6,10 +6,6 @@ impl WeakFunctor for SoloClass { type F<'a, A> = A; } -impl CarriesType for A { - type A = A; -} - impl Functor for SoloClass { fn fmap<'a, A: 'a, B: 'a, F: 'a + FnOnce(A) -> B>(f: F, fa: Self::F<'a, A>) -> Self::F<'a, B> { f(fa) diff --git a/src/func/tests.rs b/src/func/tests.rs index dd0e1ea..02efa13 100644 --- a/src/func/tests.rs +++ b/src/func/tests.rs @@ -90,7 +90,7 @@ impl AddAssign for R { pub fn fmap_respects_identity< 'a, - T: Functor + Eqr, + T: 'a + Functor + Eqr, A: 'a + Debug + PartialEq, FA0: Fn() -> T::F<'a, A>, >( @@ -101,7 +101,7 @@ pub fn fmap_respects_identity< pub fn fmap_respects_composition< 'a, - T: Functor + Eqr, + T: 'a + Functor + Eqr, A: 'a, B: 'a, C: 'a + Debug + PartialEq, @@ -122,7 +122,7 @@ pub fn fmap_respects_composition< pub fn seq_respects_identity< 'a, - T: Applicative + Eqr, + T: 'a + Applicative + Eqr, A: 'a + Debug + PartialEq, FA0: Fn() -> T::F<'a, A>, >( @@ -137,7 +137,7 @@ pub fn seq_respects_identity< pub fn seq_respects_composition< 'a, - T: Applicative + Eqr, + T: 'a + Applicative + Eqr, A: 'a, B: 'a, C: 'a + Debug + PartialEq, @@ -166,7 +166,7 @@ pub fn seq_respects_composition< pub fn seq_is_homomorphic< 'a, - T: Applicative + Eqr, + T: 'a + Applicative + Eqr, A: 'a, B: 'a + Debug + PartialEq, A0: Fn() -> A, @@ -184,7 +184,7 @@ pub fn seq_is_homomorphic< pub fn seq_respects_interchange< 'a, - T: Applicative + Eqr, + T: 'a + Applicative + Eqr, A: 'a, B: 'a + Debug + PartialEq, F: 'a + Fn(A) -> B, @@ -203,7 +203,7 @@ pub fn seq_respects_interchange< pub fn seq_can_be_expressed_via_la2< 'a, - T: Applicative + Eqr, + T: 'a + Applicative + Eqr, A: 'a, B: 'a + Debug + PartialEq, F: 'a + Fn(A) -> B, @@ -222,7 +222,7 @@ pub fn seq_can_be_expressed_via_la2< pub fn fmap_can_be_expressed_via_seq< 'a, - T: Applicative + Eqr, + T: 'a + Applicative + Eqr, A: 'a, B: 'a + Debug + PartialEq, F: 'a + Copy + Fn(A) -> B, @@ -240,7 +240,7 @@ pub fn fmap_can_be_expressed_via_seq< pub fn discard_can_be_expressed_via_seq_or_la2< 'a, - T: Applicative + Eqr, + T: 'a + Applicative + Eqr, A: 'a, B: 'a + Debug + PartialEq, FA0: 'a + Fn() -> T::F<'a, A>, @@ -262,7 +262,7 @@ pub fn discard_can_be_expressed_via_seq_or_la2< pub fn bind_respects_left_identity< 'a, - T: Monad + Eqr, + T: 'a + Monad + Eqr, A: 'a, B: 'a + Debug + PartialEq, F: 'a + Fn(A) -> T::F<'a, B>, @@ -295,7 +295,7 @@ pub fn bind_respects_right_identity< pub fn bind_is_associative< 'a, - T: Monad + Eqr, + T: 'a + Monad + Eqr, A: 'a, B: 'a, C: 'a + Debug + PartialEq, @@ -316,7 +316,7 @@ pub fn bind_is_associative< pub fn seq_can_be_expressed_via_bind< 'a, - T: Monad + Eqr, + T: 'a + Monad + Eqr, A: 'a, B: 'a + Debug + PartialEq, F: 'a + Fn(A) -> B, @@ -335,7 +335,7 @@ pub fn seq_can_be_expressed_via_bind< pub fn fmap_can_be_expressed_via_bind< 'a, - T: Monad + Eqr, + T: 'a + Monad + Eqr, A: 'a, B: 'a + Debug + PartialEq, F: 'a + Copy + Fn(A) -> B,