CarriesType + partial core
This commit is contained in:
parent
00c5239ce5
commit
0a4f00a172
112
src/core.rs
112
src/core.rs
@ -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),
|
||||
)
|
||||
}
|
||||
}
|
@ -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.
|
||||
|
@ -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 })
|
||||
}
|
||||
}
|
||||
|
@ -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()())
|
||||
}
|
||||
}
|
||||
|
@ -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)
|
||||
|
@ -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)
|
||||
|
@ -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)
|
||||
|
Loading…
Reference in New Issue
Block a user