SharedFunctor

This commit is contained in:
AF 2023-04-25 10:48:16 +00:00
parent 2ef556a71e
commit eb1c8f0167
9 changed files with 115 additions and 9 deletions

View File

@ -257,3 +257,17 @@ pub trait MonadFailOver<T: Monad>: MonadFailAny {
Self: 'a, Self: 'a,
T: 'a; T: 'a;
} }
pub trait SharedFunctor: WeakFunctor {
type Shared<'a, A: 'a + Clone>: 'a + Clone
where
Self: 'a;
fn share<'a, A: 'a + Clone>(fa: Self::F<'a, A>) -> Self::Shared<'a, A>
where
Self: 'a;
fn unshare<'a, A: 'a + Clone>(sa: Self::Shared<'a, A>) -> Self::F<'a, A>
where
Self: 'a;
}

View File

@ -124,7 +124,8 @@ impl<U: Monad, V: Monad + LocalFunctor> Monad for CompositionClass<U, V> {
impl<E, U: Monad, V: MonadFail<E> + LocalFunctor> MonadFail<E> for CompositionClass<U, V> { impl<E, U: Monad, V: MonadFail<E> + LocalFunctor> MonadFail<E> for CompositionClass<U, V> {
fn fail<'a, A: 'a>(e: E) -> Self::F<'a, A> fn fail<'a, A: 'a>(e: E) -> Self::F<'a, A>
where where
Self: 'a { Self: 'a,
{
U::pure(V::fail(e)) U::pure(V::fail(e))
} }
} }

View File

@ -5,7 +5,7 @@
use std::{future::Future, pin::Pin}; use std::{future::Future, pin::Pin};
use futures::join; use futures::{future::Shared, join, FutureExt};
use crate::func::*; use crate::func::*;
@ -107,3 +107,23 @@ impl Monad for FutureClass {
Box::pin(async { ffa.await.await }) Box::pin(async { ffa.await.await })
} }
} }
impl SharedFunctor for FutureClass {
type Shared<'a, A: 'a + Clone> = Shared<Pin<Box<dyn 'a + Future<Output = A>>>>
where
Self: 'a;
fn share<'a, A: 'a + Clone>(fa: Self::F<'a, A>) -> Self::Shared<'a, A>
where
Self: 'a,
{
fa.shared()
}
fn unshare<'a, A: 'a + Clone>(sa: Self::Shared<'a, A>) -> Self::F<'a, A>
where
Self: 'a,
{
Box::pin(sa)
}
}

View File

@ -175,3 +175,23 @@ mod option_tests {
test_suite::monad_follows_laws::<T>().unwrap(); test_suite::monad_follows_laws::<T>().unwrap();
} }
} }
impl SharedFunctor for OptionClass {
type Shared<'a, A: 'a + Clone> = Self::F<'a, A>
where
Self: 'a;
fn share<'a, A: 'a + Clone>(fa: Self::F<'a, A>) -> Self::Shared<'a, A>
where
Self: 'a,
{
fa
}
fn unshare<'a, A: 'a + Clone>(sa: Self::Shared<'a, A>) -> Self::F<'a, A>
where
Self: 'a,
{
sa
}
}

View File

@ -213,3 +213,23 @@ impl<T: Monad> MonadFailOver<T> for ResultFailOver<T> {
fa fa
} }
} }
impl<E: Clone> SharedFunctor for ResultClass<E> {
type Shared<'a, A: 'a + Clone> = Self::F<'a, A>
where
Self: 'a;
fn share<'a, A: 'a + Clone>(fa: Self::F<'a, A>) -> Self::Shared<'a, A>
where
Self: 'a,
{
fa
}
fn unshare<'a, A: 'a + Clone>(sa: Self::Shared<'a, A>) -> Self::F<'a, A>
where
Self: 'a,
{
sa
}
}

View File

@ -114,3 +114,23 @@ impl LocalFunctor for SoloClass {
fa fa
} }
} }
impl SharedFunctor for SoloClass {
type Shared<'a, A: 'a + Clone> = Self::F<'a, A>
where
Self: 'a;
fn share<'a, A: 'a + Clone>(fa: Self::F<'a, A>) -> Self::Shared<'a, A>
where
Self: 'a,
{
fa
}
fn unshare<'a, A: 'a + Clone>(sa: Self::Shared<'a, A>) -> Self::F<'a, A>
where
Self: 'a,
{
sa
}
}

View File

@ -80,8 +80,14 @@ mod tests {
#[test] #[test]
fn cannot_parse_out_of_bound_value() { fn cannot_parse_out_of_bound_value() {
assert_eq!(bool::parse_slice(&[2]).unwrap_err(), BooleanParseError::OutOfBounds(2)); assert_eq!(
assert_eq!(bool::parse_slice(&[2, 0]).unwrap_err(), BooleanParseError::OutOfBounds(2)); bool::parse_slice(&[2]).unwrap_err(),
BooleanParseError::OutOfBounds(2)
);
assert_eq!(
bool::parse_slice(&[2, 0]).unwrap_err(),
BooleanParseError::OutOfBounds(2)
);
} }
#[test] #[test]
@ -91,6 +97,9 @@ mod tests {
#[test] #[test]
fn cannot_parse_extra_tail() { fn cannot_parse_extra_tail() {
assert_eq!(bool::parse_slice(&[0, 10, 20, 30]).unwrap_err(), BooleanParseError::ExtraData(3)); assert_eq!(
bool::parse_slice(&[0, 10, 20, 30]).unwrap_err(),
BooleanParseError::ExtraData(3)
);
} }
} }

View File

@ -1,6 +1,6 @@
pub mod subset; pub mod subset;
use std::{rc::Rc, error::Error, fmt::Display}; use std::{error::Error, fmt::Display, rc::Rc};
use crate::core::*; use crate::core::*;
use crate::std::{ use crate::std::{
@ -224,7 +224,8 @@ impl<'a, Ctx: 'a + Context, F: Factory<'a, Ctx>> Factory<'a, Ctx> for BFactory<F
let key = self let key = self
.key_factory .key_factory
.deserialize(deserializer, resolver, addresses) .deserialize(deserializer, resolver, addresses)
.map_err(TreeParseError::Key)?.into(); .map_err(TreeParseError::Key)?
.into();
Ok(BNode { cl, cr, key }) Ok(BNode { cl, cr, key })
} }
@ -252,7 +253,8 @@ impl<'a, Ctx: 'a + Context, F: Factory<'a, Ctx>> Factory<'a, Ctx> for RFactory<F
let key = self let key = self
.key_factory .key_factory
.deserialize(deserializer, resolver, addresses) .deserialize(deserializer, resolver, addresses)
.map_err(TreeParseError::Key)?.into(); .map_err(TreeParseError::Key)?
.into();
Ok(RNode { cl, cr, key }) Ok(RNode { cl, cr, key })
} }