diff --git a/src/core.rs b/src/core.rs index e69de29..2c3c596 100644 --- a/src/core.rs +++ b/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 Serializer for F { + fn write(&mut self, buf: &[u8]) { + self(buf); + } +} + +pub trait Mentionable { + type Fctr: Factory; + + fn serialize(&self, serializer: F); + fn factory(&self) -> Self::Fctr; + fn topology(&self) -> Hash; +} + +pub trait Deserializer { + fn read_n_const(&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: Clone { + type Mtbl: Mentionable; + + fn deserialize(&self, deserializer: F) -> Self::Mtbl; +} + +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>; +} + +struct LocalOrigin(A); + +impl<'a, Ctx: 'a + Context, A: 'a + Mentionable> Origin<'a, Ctx> for LocalOrigin { + type Mtbl = A; + + fn factory(&self) -> >::Fctr { + self.0.factory() + } + + fn resolve(self: Box) -> <::T as WeakFunctor>::F<'a, Self::Mtbl> { + ::pure(self.0) + } +} + +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 + } +} + +pub struct HashPoint<'a, Ctx: Context, A: Mentionable> { + point: Hash, + origin: Box>, +} + +impl<'a, Ctx: 'a + Context, A: 'a + Mentionable> HashPoint<'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_values>(point: Hash, origin: O) -> Self { + Self::from_fields(point, Box::new(origin)) + } + + fn resolve(self) -> <::T as WeakFunctor>::F<'a, A> { + self.origin.resolve() + } +} + +impl<'a, Ctx: 'a + Context, A: 'a + Mentionable> From 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), + ) + } +} diff --git a/src/func.rs b/src/func.rs index c2cf7b4..98a6136 100644 --- a/src/func.rs +++ b/src/func.rs @@ -7,7 +7,11 @@ pub mod test_suite; pub mod tests; pub trait WeakFunctor { - type F<'a, A>; + type F<'a, A>: CarriesType; +} + +pub trait CarriesType { + type A; } /// Rust-specific implementation of [Functor], respecting `move` semantics. diff --git a/src/func/classes/futureclass.rs b/src/func/classes/futureclass.rs index ef88273..ab99c12 100644 --- a/src/func/classes/futureclass.rs +++ b/src/func/classes/futureclass.rs @@ -10,6 +10,10 @@ 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) }) @@ -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 }) } } diff --git a/src/func/classes/lazyclass.rs b/src/func/classes/lazyclass.rs index a412899..42cb370 100644 --- a/src/func/classes/lazyclass.rs +++ b/src/func/classes/lazyclass.rs @@ -6,6 +6,10 @@ 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())) @@ -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()()) } } diff --git a/src/func/classes/optionclass.rs b/src/func/classes/optionclass.rs index c246b70..85b16e0 100644 --- a/src/func/classes/optionclass.rs +++ b/src/func/classes/optionclass.rs @@ -6,6 +6,10 @@ 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 e59715f..8b6db3f 100644 --- a/src/func/classes/resultclass.rs +++ b/src/func/classes/resultclass.rs @@ -6,6 +6,10 @@ 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 f04d3e0..c063beb 100644 --- a/src/func/classes/soloclass.rs +++ b/src/func/classes/soloclass.rs @@ -6,6 +6,10 @@ 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)