CompositionClass + two RCs
This commit is contained in:
parent
bfd7f95407
commit
f82020f766
53
src/core.rs
53
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<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),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
53
src/func.rs
53
src/func.rs
@ -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)
|
||||
}
|
||||
|
@ -1,3 +1,4 @@
|
||||
pub mod compositionclass;
|
||||
pub mod futureclass;
|
||||
pub mod lazyclass;
|
||||
pub mod optionclass;
|
||||
|
55
src/func/classes/compositionclass.rs
Normal file
55
src/func/classes/compositionclass.rs
Normal 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)
|
||||
}
|
||||
}
|
@ -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) })
|
||||
|
@ -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()))
|
||||
|
@ -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)
|
||||
|
@ -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)
|
||||
|
@ -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)
|
||||
|
@ -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,
|
||||
|
Loading…
Reference in New Issue
Block a user