CarriesType + partial core

This commit is contained in:
AF 2023-03-13 00:22:50 +00:00
parent 00c5239ce5
commit 0a4f00a172
7 changed files with 139 additions and 5 deletions

View File

@ -0,0 +1,112 @@
use crate::func::*;
pub trait Context {
type T: Monad;
fn hash(s: &[u8]) -> Hash;
}
type Hash = [u8; 32];
pub trait Serializer {
fn write(&mut self, buf: &[u8]);
}
impl<F: FnMut(&[u8])> Serializer for F {
fn write(&mut self, buf: &[u8]) {
self(buf);
}
}
pub trait Mentionable<Ctx: Context> {
type Fctr: Factory<Ctx, Mtbl = Self>;
fn serialize<F: Serializer>(&self, serializer: F);
fn factory(&self) -> Self::Fctr;
fn topology(&self) -> Hash;
}
pub trait Deserializer {
fn read_n_const<const N: usize>(&mut self) -> Result<[u8; N], &[u8]>;
fn read_n(&mut self, n: usize) -> &[u8];
fn read_all(&mut self, n: usize) -> &[u8];
}
pub trait Factory<Ctx: Context>: Clone {
type Mtbl: Mentionable<Ctx, Fctr = Self>;
fn deserialize<F: Deserializer>(&self, deserializer: F) -> Self::Mtbl;
}
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>;
}
struct LocalOrigin<A>(A);
impl<'a, Ctx: 'a + Context, A: 'a + Mentionable<Ctx>> Origin<'a, Ctx> for LocalOrigin<A> {
type Mtbl = A;
fn factory(&self) -> <Self::Mtbl as Mentionable<Ctx>>::Fctr {
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)
}
}
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
}
}
pub struct HashPoint<'a, Ctx: Context, A: Mentionable<Ctx>> {
point: Hash,
origin: Box<dyn Origin<'a, Ctx, Mtbl = A>>,
}
impl<'a, Ctx: 'a + Context, A: 'a + Mentionable<Ctx>> HashPoint<'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_values<O: Origin<'a, Ctx, Mtbl = A>>(point: Hash, origin: O) -> Self {
Self::from_fields(point, Box::new(origin))
}
fn resolve(self) -> <<Ctx as Context>::T as WeakFunctor>::F<'a, A> {
self.origin.resolve()
}
}
impl<'a, Ctx: 'a + Context, A: 'a + Mentionable<Ctx>> From<A> for HashPoint<'a, Ctx, A> {
fn from(value: A) -> Self {
Self::from_values(
Ctx::hash(Self::prepare_bytes_for_hashing(&value).as_slice()),
LocalOrigin(value),
)
}
}

View File

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

View File

@ -10,6 +10,10 @@ 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) })
@ -70,8 +74,7 @@ impl Monad for FutureClass {
Box::pin(async { f(fa.await).await })
}
fn join<'a, A: 'a>(ffa: Self::F<'a, Self::F<'a, A>>) -> Self::F<'a, A>
{
fn join<'a, A: 'a>(ffa: Self::F<'a, Self::F<'a, A>>) -> Self::F<'a, A> {
Box::pin(async { ffa.await.await })
}
}

View File

@ -6,6 +6,10 @@ 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()))
@ -65,8 +69,7 @@ impl Monad for LazyClass {
Box::new(|| f(fa())())
}
fn join<'a, A: 'a>(ffa: Self::F<'a, Self::F<'a, A>>) -> Self::F<'a, A>
{
fn join<'a, A: 'a>(ffa: Self::F<'a, Self::F<'a, A>>) -> Self::F<'a, A> {
Box::new(|| ffa()())
}
}

View File

@ -6,6 +6,10 @@ 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,6 +6,10 @@ 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,6 +6,10 @@ 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)