CompositionClass + two RCs

This commit is contained in:
AF 2023-03-17 09:26:56 +00:00
parent bfd7f95407
commit f82020f766
10 changed files with 129 additions and 79 deletions

View File

@ -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<Ctx: Context>: Clone {
type Mtbl: Mentionable<Ctx, Fctr = Self>;
type ParseError: Error;
fn deserialize<F: Deserializer>(&self, deserializer: F) -> Self::Mtbl;
fn deserialize<F: Deserializer>(&self, deserializer: F) -> Result<Self::Mtbl, Self::ParseError>;
}
pub trait Origin<'a, Ctx: Context>: 'a {
type Mtbl: Mentionable<Ctx>;
fn factory(&self) -> <Self::Mtbl as Mentionable<Ctx>>::Fctr;
fn resolve(self: Box<Self>) -> <<Ctx as Context>::T as WeakFunctor>::F<'a, Self::Mtbl>;
fn resolve(&self) -> <<Ctx as Context>::T as WeakFunctor>::F<'a, Rc<Self::Mtbl>>;
}
struct LocalOrigin<A>(A);
struct LocalOrigin<A>(Rc<A>);
impl<'a, Ctx: 'a + Context, A: 'a + Mentionable<Ctx>> Origin<'a, Ctx> for LocalOrigin<A> {
type Mtbl = A;
@ -53,60 +56,48 @@ impl<'a, Ctx: 'a + Context, A: 'a + Mentionable<Ctx>> Origin<'a, Ctx> for LocalO
self.0.factory()
}
fn resolve(self: Box<Self>) -> <<Ctx as Context>::T as WeakFunctor>::F<'a, Self::Mtbl> {
<Ctx::T as Applicative>::pure(self.0)
fn resolve(&self) -> <<Ctx as Context>::T as WeakFunctor>::F<'a, Rc<Self::Mtbl>> {
<Ctx::T as Applicative>::pure(self.0.clone())
}
}
struct ApplicativeOrigin<'a, Ctx: Context, A: Mentionable<Ctx>>(
<<Ctx as Context>::T as WeakFunctor>::F<'a, A>,
A::Fctr,
);
impl<'a, Ctx: 'a + Context, A: 'a + Mentionable<Ctx>> Origin<'a, Ctx>
for ApplicativeOrigin<'a, Ctx, A>
{
type Mtbl = A;
fn factory(&self) -> <Self::Mtbl as Mentionable<Ctx>>::Fctr {
self.1.clone()
}
fn resolve(self: Box<Self>) -> <<Ctx as Context>::T as WeakFunctor>::F<'a, Self::Mtbl> {
self.0
impl<A> From<A> for LocalOrigin<A> {
fn from(value: A) -> Self {
LocalOrigin(value.into())
}
}
pub struct HashPoint<'a, Ctx: Context, A: Mentionable<Ctx>> {
point: Hash,
origin: Box<dyn Origin<'a, Ctx, Mtbl = A>>,
#[derive(Clone)]
pub struct Point<'a, Ctx: Context, A: Mentionable<Ctx>> {
pub point: Hash,
pub origin: Rc<dyn Origin<'a, Ctx, Mtbl = A>>,
}
impl<'a, Ctx: 'a + Context, A: 'a + Mentionable<Ctx>> HashPoint<'a, Ctx, A> {
impl<'a, Ctx: 'a + Context, A: 'a + Mentionable<Ctx>> Point<'a, Ctx, A> {
fn prepare_bytes_for_hashing(mentioned: &A) -> Vec<u8> {
let mut vec = mentioned.topology().to_vec();
mentioned.serialize(|x: &[u8]| vec.extend(x.iter()));
vec
}
fn from_fields(point: Hash, origin: Box<dyn Origin<'a, Ctx, Mtbl = A>>) -> Self {
HashPoint { point, origin }
fn from_fields(point: Hash, origin: Rc<dyn Origin<'a, Ctx, Mtbl = A>>) -> Self {
Point { point, origin }
}
fn from_values<O: Origin<'a, Ctx, Mtbl = A>>(point: Hash, origin: O) -> Self {
Self::from_fields(point, Box::new(origin))
Self::from_fields(point, Rc::new(origin))
}
fn resolve(self) -> <<Ctx as Context>::T as WeakFunctor>::F<'a, A> {
pub fn resolve(&self) -> <<Ctx as Context>::T as WeakFunctor>::F<'a, Rc<A>> {
self.origin.resolve()
}
}
impl<'a, Ctx: 'a + Context, A: 'a + Mentionable<Ctx>> From<A> for HashPoint<'a, Ctx, A> {
impl<'a, Ctx: 'a + Context, A: 'a + Mentionable<Ctx>> From<A> 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),
)
}
}

View File

@ -7,11 +7,7 @@ pub mod test_suite;
pub mod tests;
pub trait WeakFunctor {
type F<'a, A>: CarriesType<Self, A = A>;
}
pub trait CarriesType<T: WeakFunctor + ?Sized> {
type A;
type F<'a, A>;
}
/// Rust-specific implementation of [Functor], respecting `move` semantics.
@ -55,13 +51,21 @@ pub trait CarriesType<T: WeakFunctor + ?Sized> {
/// ```
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)
}

View File

@ -1,3 +1,4 @@
pub mod compositionclass;
pub mod futureclass;
pub mod lazyclass;
pub mod optionclass;

View File

@ -0,0 +1,55 @@
use crate::func::*;
struct CompositionClass<U, V>(U, V);
impl<U: WeakFunctor, V: WeakFunctor> WeakFunctor for CompositionClass<U, V> {
type F<'a, A> = U::F<'a, V::F<'a, A>>;
}
impl<U: Functor, V: Functor> Functor for CompositionClass<U, V> {
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<U: ApplicativeLA2, V: ApplicativeSeq> ApplicativeSeq for CompositionClass<U, V> {
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<U: ApplicativeLA2, V: ApplicativeLA2> ApplicativeLA2 for CompositionClass<U, V> {
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)
}
}

View File

@ -10,10 +10,6 @@ impl WeakFunctor for FutureClass {
type F<'a, A> = Pin<Box<dyn 'a + Future<Output = A>>>;
}
impl<'a, A> CarriesType<FutureClass> for Pin<Box<dyn 'a + Future<Output = A>>> {
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) })

View File

@ -6,10 +6,6 @@ impl WeakFunctor for LazyClass {
type F<'a, A> = Box<dyn 'a + FnOnce() -> A>;
}
impl<'a, A> CarriesType<LazyClass> for Box<dyn 'a + FnOnce() -> 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()))

View File

@ -6,10 +6,6 @@ impl WeakFunctor for OptionClass {
type F<'a, A> = Option<A>;
}
impl<A> CarriesType<OptionClass> for Option<A> {
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)

View File

@ -6,10 +6,6 @@ impl<E> WeakFunctor for ResultClass<E> {
type F<'a, A> = Result<A, E>;
}
impl<A, E> CarriesType<ResultClass<E>> for Result<A, E> {
type A = A;
}
impl<E> Functor for ResultClass<E> {
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)

View File

@ -6,10 +6,6 @@ impl WeakFunctor for SoloClass {
type F<'a, A> = A;
}
impl<A> CarriesType<SoloClass> 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)

View File

@ -90,7 +90,7 @@ impl AddAssign<R> 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,