Send everything
All checks were successful
buildbot/cargo fmt (1.71) Build done.
buildbot/cargo doc (1.71) Build done.
buildbot/cargo clippy (1.71) Build done.
buildbot/cargo test (1.65) Build done.
buildbot/cargo clippy (1.65) Build done.

This commit is contained in:
AF 2023-08-11 00:14:44 +00:00
parent 69c7a1511e
commit dc98e38b8f
60 changed files with 927 additions and 670 deletions

View File

@ -9,18 +9,18 @@ pub fn derive_shared_functor(input: proc_macro::TokenStream) -> proc_macro::Toke
let (impl_generics, ty_generics, where_clause) = generics.split_for_impl();
let expanded = quote! {
impl #impl_generics SharedFunctorAny for #name #ty_generics #where_clause {
type SharedAny<'a, A: 'a + Clone> = Self::FAny<'a, A>
type SharedAny<'a, A: 'a + Send + Sync + Clone> = Self::FAny<'a, A>
where
Self: 'a;
fn share<'a, A: 'a + Clone>(fa: Self::FAny<'a, A>) -> Self::SharedAny<'a, A>
fn share<'a, A: 'a + Send + Sync + Clone>(fa: Self::FAny<'a, A>) -> Self::SharedAny<'a, A>
where
Self: 'a,
{
fa
}
fn unshare<'a, A: 'a + Clone>(sa: Self::SharedAny<'a, A>) -> Self::FAny<'a, A>
fn unshare<'a, A: 'a + Send + Sync + Clone>(sa: Self::SharedAny<'a, A>) -> Self::FAny<'a, A>
where
Self: 'a,
{

View File

@ -33,7 +33,7 @@ pub trait AtomicBase: 'static + Send + Sync + Clone + Serializable {
/// Equivalent of [`FactoryBase::ParseError`].
///
/// [`FactoryBase::ParseError`]: crate::rcore::FactoryBase::ParseError
type AParseError: Error;
type AParseError: Error + Send;
}
/// This trait combines functionality of [`Mentionable`] and [`Factory`],

View File

@ -18,10 +18,10 @@ pub type KeySplit<'a, BT> = (<BT as BinaryTrees<'a>>::Tree, <BT as BinaryTrees<'
pub type BTWrap<'a, BT, A> = WrapC<'a, A, BT>;
pub trait BinaryTrees<'a>: FunctorContext<'a, T = Self::_Tm> + Clone {
type Node: 'a;
type Reference: 'a;
type Tree: 'a;
type Key: 'a + Clone;
type Node: 'a + Send;
type Reference: 'a + Send;
type Tree: 'a + Send;
type Key: 'a + Send + Clone;
type Comparator: Comparator<Self::Key>;
type _Tm: Monad<'a>;
@ -153,7 +153,7 @@ impl Display for HeightError {
pub trait BinaryTreesHeight<'a>: BinaryTrees<'a> {
fn height(&self, tree: &Self::Tree) -> u64;
fn height_error<T: 'a>(&self, error: HeightError) -> BTWrap<'a, Self, T>;
fn height_error<T: 'a + Send>(&self, error: HeightError) -> BTWrap<'a, Self, T>;
}
pub trait BinaryTreesTryJoin<'a>: BinaryTrees<'a> {

View File

@ -50,10 +50,10 @@ pub trait BinaryTreesAvl<'a>:
}
}
fn assume_bind<T>(
fn assume_bind<T: Send>(
self,
tree: &Self::Tree,
f: impl 'a + FnOnce(Self, Self::Tree, Self::Key, Self::Tree) -> BTWrap<'a, Self, T>,
f: impl 'a + Send + FnOnce(Self, Self::Tree, Self::Key, Self::Tree) -> BTWrap<'a, Self, T>,
) -> BTWrap<'a, Self, T> {
Self::bind(self.assume_node(tree), move |node| {
let (tl, tr, key) = self.split(&node);

View File

@ -5,9 +5,9 @@ use super::{avl::*, bound::*, *};
pub trait BinaryTreesUnbalanced<'a>: BinaryTreesHeight<'a> {
fn tree_of_with_height(&self, node: Self::Node, height: u64) -> BTWrap<'a, Self, Self::Tree>;
fn balancing_error<T: 'a>(&self, error: BalancingError) -> BTWrap<'a, Self, T>;
fn balancing_error<T: 'a + Send>(&self, error: BalancingError) -> BTWrap<'a, Self, T>;
fn balancing_bind<A: 'a, B: 'a>(
fn balancing_bind<A: 'a, B: 'a + Send>(
&self,
ra: Result<A, BalancingError>,
f: impl FnOnce(A) -> BTWrap<'a, Self, B>,
@ -153,7 +153,7 @@ impl<'a, BT: BinaryTreesUnbalanced<'a>> BinaryTreesHeight<'a> for BalancedTrees<
self.0.height(tree)
}
fn height_error<T: 'a>(&self, error: HeightError) -> BTWrap<'a, Self, T> {
fn height_error<T: 'a + Send>(&self, error: HeightError) -> BTWrap<'a, Self, T> {
self.0.height_error(error)
}
}
@ -176,7 +176,10 @@ impl<'a, BT: BinaryTreesUnbalanced<'a> + BinaryTreesTryJoin<'a>> BinaryTreesTryJ
impl<'a, BT: BinaryTreesUnbalanced<'a> + BinaryTreesBindable<'a>> BinaryTreesBindable<'a>
for BalancedTrees<BT>
{
fn bounds_error<T: 'a>(&self, error: bounds::BoundsError<Self::Key>) -> BTWrap<'a, Self, T> {
fn bounds_error<T: 'a + Send>(
&self,
error: bounds::BoundsError<Self::Key>,
) -> BTWrap<'a, Self, T> {
self.0.bounds_error(error)
}
}

View File

@ -38,9 +38,9 @@ impl<'a, BT: FunctorContext<'a>> FunctorContext<'a> for BoundTrees<BT> {
}
pub trait BinaryTreesBindable<'a>: BinaryTrees<'a> {
fn bounds_error<T: 'a>(&self, error: BoundsError<Self::Key>) -> BTWrap<'a, Self, T>;
fn bounds_error<T: 'a + Send>(&self, error: BoundsError<Self::Key>) -> BTWrap<'a, Self, T>;
fn bounds_bind<A: 'a, B: 'a>(
fn bounds_bind<A: 'a + Send, B: 'a + Send>(
&self,
ra: Result<A, BoundsError<Self::Key>>,
f: impl FnOnce(A) -> BTWrap<'a, Self, B>,
@ -169,7 +169,7 @@ impl<'a, BT: BinaryTreesBindable<'a> + BinaryTreesHeight<'a>> BinaryTreesHeight<
self.0.height(&tree.bound)
}
fn height_error<T: 'a>(&self, error: HeightError) -> BTWrap<'a, Self, T> {
fn height_error<T: 'a + Send>(&self, error: HeightError) -> BTWrap<'a, Self, T> {
self.0.height_error(error)
}
}

View File

@ -15,7 +15,7 @@ pub enum Comparison {
/// assert_eq!(DefaultComparator.compare(&2, &2), Comparison::E);
/// assert_eq!(DefaultComparator.compare(&3, &1), Comparison::R);
/// ```
pub trait Comparator<A> {
pub trait Comparator<A>: Send + Sync {
fn compare(&self, kl: &A, kr: &A) -> Comparison;
fn equal(&self, kl: &A, kr: &A) -> bool {
@ -40,10 +40,10 @@ pub struct RcComparator<C>(C);
mod rc_comparator_impl {
use super::*;
use std::rc::Rc;
use std::sync::Arc;
impl<A, C: Comparator<A>> Comparator<Rc<A>> for RcComparator<C> {
fn compare(&self, kl: &Rc<A>, kr: &Rc<A>) -> Comparison {
impl<A, C: Comparator<A>> Comparator<Arc<A>> for RcComparator<C> {
fn compare(&self, kl: &Arc<A>, kr: &Arc<A>) -> Comparison {
self.0.compare(kl, kr)
}
}

View File

@ -6,14 +6,14 @@ type Frwa<'a, A, E0, E1, Fallible> =
type Wwa<'a, A, E0, E1, Fallible> = WrapE<'a, WrapE<'a, A, E0, Fallible>, E1, Fallible>;
trait SpeculativeFailImpl<'a>: MonadFailAny<'a> {
fn _speculative_a_wb<A: 'a, B: 'a, E0: 'a, E1: 'a>(
fn _speculative_a_wb<A: 'a + Send, B: 'a + Send, E0: 'a + Send, E1: 'a + Send>(
a: A,
wb: WrapE<'a, B, E0, Self>,
) -> WrapE<'a, (A, B), Result<E0, E1>, Self> {
Self::map_err(<Self::W<E0> as Functor>::fmap(wb, |b| (a, b)), Ok)
}
fn _speculative_ra_wb<A: 'a, B: 'a, E0: 'a, E1: 'a>(
fn _speculative_ra_wb<A: 'a + Send, B: 'a + Send, E0: 'a + Send, E1: 'a + Send>(
ra: Result<A, E0>,
wb: WrapE<'a, B, E0, Self>,
) -> WrapE<'a, (A, B), Result<E0, E1>, Self> {
@ -23,7 +23,7 @@ trait SpeculativeFailImpl<'a>: MonadFailAny<'a> {
}
}
fn _speculative_ra_rwb<A: 'a, B: 'a, E0: 'a, E1: 'a>(
fn _speculative_ra_rwb<A: 'a + Send, B: 'a + Send, E0: 'a + Send, E1: 'a + Send>(
ra: Result<A, E0>,
rwb: Result<WrapE<'a, B, E0, Self>, E1>,
) -> WrapE<'a, (A, B), Result<E0, E1>, Self> {
@ -33,7 +33,7 @@ trait SpeculativeFailImpl<'a>: MonadFailAny<'a> {
}
}
fn _speculative_ra_frwb<A: 'a, B: 'a, E0: 'a, E1: 'a>(
fn _speculative_ra_frwb<A: 'a + Send, B: 'a + Send, E0: 'a + Send, E1: 'a + Send>(
ra: Result<A, E0>,
frwb: Frwa<'a, B, E0, E1, Self>,
) -> WrapE<'a, (A, B), Result<E0, E1>, Self> {
@ -42,14 +42,14 @@ trait SpeculativeFailImpl<'a>: MonadFailAny<'a> {
}))
}
fn _speculative_fra_wb<A: 'a, B: 'a, E0: 'a>(
fn _speculative_fra_wb<A: 'a + Send, B: 'a + Send, E0: 'a + Send>(
fra: Wrap<'a, Result<A, E0>, Self::T>,
wb: WrapE<'a, B, E0, Self>,
) -> WrapE<'a, (A, B), E0, Self> {
<Self::W<E0> as ApplicativeTuple>::tuple((Self::stuff(fra), wb))
}
fn _speculative_wa_frwb<A: 'a, B: 'a, E0: 'a, E1: 'a>(
fn _speculative_wa_frwb<A: 'a + Send, B: 'a + Send, E0: 'a + Send, E1: 'a + Send>(
wa: WrapE<'a, A, E0, Self>,
frwb: Frwa<'a, B, E0, E1, Self>,
) -> WrapE<'a, (A, B), Result<E0, E1>, Self> {
@ -67,7 +67,7 @@ trait SpeculativeFailImpl<'a>: MonadFailAny<'a> {
))
}
fn _speculative_frwa_wb<A: 'a, B: 'a, E0: 'a, E1: 'a>(
fn _speculative_frwa_wb<A: 'a + Send, B: 'a + Send, E0: 'a + Send, E1: 'a + Send>(
frwa: Frwa<'a, A, E0, E1, Self>,
wb: WrapE<'a, B, E0, Self>,
) -> WrapE<'a, (A, B), Result<E0, E1>, Self> {
@ -77,7 +77,7 @@ trait SpeculativeFailImpl<'a>: MonadFailAny<'a> {
)
}
fn _speculative<A: 'a, B: 'a, E0: 'a, E1: 'a>(
fn _speculative<A: 'a + Send, B: 'a + Send, E0: 'a + Send, E1: 'a + Send>(
wwa: Wwa<'a, A, E0, E1, Self>,
wwb: Wwa<'a, B, E0, E1, Self>,
) -> WrapE<'a, (A, B), Result<E0, E1>, Self> {
@ -98,7 +98,7 @@ trait SpeculativeFailImpl<'a>: MonadFailAny<'a> {
}
pub trait SpeculativeFail<'a>: MonadFailAny<'a> {
fn speculative<A: 'a, B: 'a, E0: 'a, E1: 'a>(
fn speculative<A: 'a + Send, B: 'a + Send, E0: 'a + Send, E1: 'a + Send>(
wwa: Wwa<'a, A, E0, E1, Self>,
wwb: Wwa<'a, B, E0, E1, Self>,
) -> WrapE<'a, (A, B), Result<E0, E1>, Self> {

View File

@ -2,30 +2,36 @@
pub mod algorithms;
use std::rc::Rc;
use std::sync::Arc;
use crate::flow::comparator::*;
use crate::func::*;
pub type Split<'a, T, A, D> = (
Rc<dyn TraversibleBinaryTree<'a, T, A, D>>,
Rc<dyn TraversibleBinaryTree<'a, T, A, D>>,
Arc<dyn TraversibleBinaryTree<'a, T, A, D>>,
Arc<dyn TraversibleBinaryTree<'a, T, A, D>>,
A,
);
pub trait TraversibleBinaryNode<'a, T: Monad<'a>, A: 'a, D: 'a + PartialEq>: 'a {
pub trait TraversibleBinaryNode<'a, T: Monad<'a>, A: 'a, D: 'a + PartialEq>:
'a + Send + Sync
{
fn split(&self) -> Split<'a, T, A, D>;
fn to_tree(self: Rc<Self>) -> Rc<dyn TraversibleBinaryTree<'a, T, A, D>>;
fn to_tree(self: Arc<Self>) -> Arc<dyn TraversibleBinaryTree<'a, T, A, D>>;
}
pub trait TraversibleBinaryReference<'a, T: Monad<'a>, A: 'a, D: 'a + PartialEq>: 'a {
fn resolve(&self) -> Wrap<'a, Rc<dyn TraversibleBinaryNode<'a, T, A, D>>, T>;
pub trait TraversibleBinaryReference<'a, T: Monad<'a>, A: 'a, D: 'a + PartialEq>:
'a + Send + Sync
{
fn resolve(&self) -> Wrap<'a, Arc<dyn TraversibleBinaryNode<'a, T, A, D>>, T>;
/// This should be enough to compare reference for equality.
fn data(&self) -> D;
}
pub trait TraversibleBinaryTree<'a, T: Monad<'a>, A: 'a, D: 'a + PartialEq>: 'a {
fn refer(&self) -> Option<Rc<dyn TraversibleBinaryReference<'a, T, A, D>>>;
pub trait TraversibleBinaryTree<'a, T: Monad<'a>, A: 'a, D: 'a + PartialEq>:
'a + Send + Sync
{
fn refer(&self) -> Option<Arc<dyn TraversibleBinaryReference<'a, T, A, D>>>;
}

View File

@ -1,8 +1,8 @@
use crate::{flow::traversible::*, func::class_prelude::MonadFail};
pub fn n_contains<'a, T: MonadFail<'a, ()>, A: 'a + Clone, D: 'a + PartialEq>(
pub fn n_contains<'a, T: MonadFail<'a, ()>, A: 'a + Send + Clone, D: 'a + PartialEq>(
comparator: &'a dyn Comparator<A>,
n_set: Rc<dyn TraversibleBinaryNode<'a, T, A, D>>,
n_set: Arc<dyn TraversibleBinaryNode<'a, T, A, D>>,
key: A,
) -> T::F<()> {
let (t_setl, t_setr, k_set) = n_set.split();
@ -13,17 +13,17 @@ pub fn n_contains<'a, T: MonadFail<'a, ()>, A: 'a + Clone, D: 'a + PartialEq>(
}
}
pub fn r_contains<'a, T: MonadFail<'a, ()>, A: 'a + Clone, D: 'a + PartialEq>(
pub fn r_contains<'a, T: MonadFail<'a, ()>, A: 'a + Send + Clone, D: 'a + PartialEq>(
comparator: &'a dyn Comparator<A>,
r_set: Rc<dyn TraversibleBinaryReference<'a, T, A, D>>,
r_set: Arc<dyn TraversibleBinaryReference<'a, T, A, D>>,
key: A,
) -> T::F<()> {
T::bind(r_set.resolve(), |n_set| n_contains(comparator, n_set, key))
}
pub fn t_contains<'a, T: MonadFail<'a, ()>, A: 'a + Clone, D: 'a + PartialEq>(
pub fn t_contains<'a, T: MonadFail<'a, ()>, A: 'a + Send + Clone, D: 'a + PartialEq>(
comparator: &'a dyn Comparator<A>,
t_set: Rc<dyn TraversibleBinaryTree<'a, T, A, D>>,
t_set: Arc<dyn TraversibleBinaryTree<'a, T, A, D>>,
key: A,
) -> T::F<()> {
match t_set.refer() {

View File

@ -6,16 +6,18 @@ fn and(_l: (), _r: ()) {}
struct SubsetContext<'a, T: MonadFail<'a, ()>, A: 'a, D: 'a + PartialEq> {
comparator: &'a dyn Comparator<A>,
n_subset: Rc<dyn TraversibleBinaryNode<'a, T, A, D>>,
n_superset: Rc<dyn TraversibleBinaryNode<'a, T, A, D>>,
n_subset: Arc<dyn TraversibleBinaryNode<'a, T, A, D>>,
n_superset: Arc<dyn TraversibleBinaryNode<'a, T, A, D>>,
k_l: Option<A>,
k_r: Option<A>,
t_superl: Rc<dyn TraversibleBinaryTree<'a, T, A, D>>,
t_superr: Rc<dyn TraversibleBinaryTree<'a, T, A, D>>,
t_superl: Arc<dyn TraversibleBinaryTree<'a, T, A, D>>,
t_superr: Arc<dyn TraversibleBinaryTree<'a, T, A, D>>,
k_super: A,
}
impl<'a, T: 'a + MonadFail<'a, ()>, A: 'a + Clone, D: 'a + PartialEq> SubsetContext<'a, T, A, D> {
impl<'a, T: 'a + MonadFail<'a, ()>, A: 'a + Send + Clone, D: 'a + PartialEq>
SubsetContext<'a, T, A, D>
{
fn on_l(self, (t_subl, t_subr, k_sub): Split<'a, T, A, D>) -> T::F<()> {
T::la2(
algorithms::contains::t_contains(self.comparator, self.t_superl.clone(), k_sub.clone()),
@ -148,10 +150,10 @@ fn outside_r<A>(comparator: &dyn Comparator<A>, k_r: &Option<A>, k_super: &A) ->
}
}
pub fn n_subset_of_n<'a, T: MonadFail<'a, ()>, A: 'a + Clone, D: 'a + PartialEq>(
pub fn n_subset_of_n<'a, T: MonadFail<'a, ()>, A: 'a + Send + Clone, D: 'a + PartialEq>(
comparator: &'a dyn Comparator<A>,
n_subset: Rc<dyn TraversibleBinaryNode<'a, T, A, D>>,
n_superset: Rc<dyn TraversibleBinaryNode<'a, T, A, D>>,
n_subset: Arc<dyn TraversibleBinaryNode<'a, T, A, D>>,
n_superset: Arc<dyn TraversibleBinaryNode<'a, T, A, D>>,
k_l: Option<A>,
k_r: Option<A>,
) -> T::F<()> {
@ -169,10 +171,15 @@ pub fn n_subset_of_n<'a, T: MonadFail<'a, ()>, A: 'a + Clone, D: 'a + PartialEq>
.test_optimised()
}
pub fn r_subset_of_r_unoptimised<'a, T: MonadFail<'a, ()>, A: 'a + Clone, D: 'a + PartialEq>(
pub fn r_subset_of_r_unoptimised<
'a,
T: MonadFail<'a, ()>,
A: 'a + Send + Clone,
D: 'a + PartialEq,
>(
comparator: &'a dyn Comparator<A>,
r_subset: Rc<dyn TraversibleBinaryReference<'a, T, A, D>>,
r_superset: Rc<dyn TraversibleBinaryReference<'a, T, A, D>>,
r_subset: Arc<dyn TraversibleBinaryReference<'a, T, A, D>>,
r_superset: Arc<dyn TraversibleBinaryReference<'a, T, A, D>>,
k_l: Option<A>,
k_r: Option<A>,
) -> T::F<()> {
@ -183,9 +190,9 @@ pub fn r_subset_of_r_unoptimised<'a, T: MonadFail<'a, ()>, A: 'a + Clone, D: 'a
)
}
fn r_subset_of_r_optimised<'a, T: MonadFail<'a, ()>, A: 'a + Clone, D: 'a + PartialEq>(
r_subset: Rc<dyn TraversibleBinaryReference<'a, T, A, D>>,
r_superset: Rc<dyn TraversibleBinaryReference<'a, T, A, D>>,
fn r_subset_of_r_optimised<'a, T: MonadFail<'a, ()>, A: 'a + Send + Clone, D: 'a + PartialEq>(
r_subset: Arc<dyn TraversibleBinaryReference<'a, T, A, D>>,
r_superset: Arc<dyn TraversibleBinaryReference<'a, T, A, D>>,
comparator: &'a dyn Comparator<A>,
k_l: Option<A>,
k_r: Option<A>,
@ -197,10 +204,10 @@ fn r_subset_of_r_optimised<'a, T: MonadFail<'a, ()>, A: 'a + Clone, D: 'a + Part
}
}
pub fn t_subset_of_t<'a, T: MonadFail<'a, ()>, A: 'a + Clone, D: 'a + PartialEq>(
pub fn t_subset_of_t<'a, T: MonadFail<'a, ()>, A: 'a + Send + Clone, D: 'a + PartialEq>(
comparator: &'a dyn Comparator<A>,
t_subset: Rc<dyn TraversibleBinaryTree<'a, T, A, D>>,
t_superset: Rc<dyn TraversibleBinaryTree<'a, T, A, D>>,
t_subset: Arc<dyn TraversibleBinaryTree<'a, T, A, D>>,
t_superset: Arc<dyn TraversibleBinaryTree<'a, T, A, D>>,
k_l: Option<A>,
k_r: Option<A>,
) -> T::F<()> {

View File

@ -30,8 +30,8 @@ pub use self::extensions::MonadExt;
/// Part of Haskell's `Functor f` responsible for having `f a`.
///
/// <https://hackage.haskell.org/package/base-4.18.0.0/docs/Data-Functor.html>
pub trait WeakFunctor<'a>: 'a {
type F<A: 'a>: 'a;
pub trait WeakFunctor<'a>: 'a + Send {
type F<A: 'a + Send>: 'a + Send;
}
pub type Wrap<'a, A, T> = <T as WeakFunctor<'a>>::F<A>;
@ -43,15 +43,18 @@ pub trait Functor<'a>: WeakFunctor<'a> {
/// Equivalent or Haskell's `fmap`.
/// Due to Rust limitations, it's not a `function->function` conversion.
/// For that see [`derivations::fmap`].
fn fmap<A: 'a, B: 'a>(fa: Self::F<A>, f: impl 'a + FnOnce(A) -> B) -> Self::F<B>;
fn fmap<A: 'a + Send, B: 'a + Send>(
fa: Self::F<A>,
f: impl 'a + Send + FnOnce(A) -> B,
) -> Self::F<B>;
/// Equivalent of Haskell's `$>`/`<$`.
fn replace<A: 'a, B: 'a>(fa: Self::F<A>, b: B) -> Self::F<B> {
fn replace<A: 'a + Send, B: 'a + Send>(fa: Self::F<A>, b: B) -> Self::F<B> {
Self::fmap(fa, |_| b)
}
/// Equivalent of Haskell's `void`.
fn void<A: 'a>(fa: Self::F<A>) -> Self::F<()> {
fn void<A: 'a + Send>(fa: Self::F<A>) -> Self::F<()> {
Self::replace(fa, ())
}
}
@ -59,29 +62,32 @@ pub trait Functor<'a>: WeakFunctor<'a> {
/// Part of [`Applicative`] responsible for Haskell's value lifting, `pure`.
pub trait Pure<'a>: Functor<'a> {
/// Equivalent of Haskell's `pure`/`return`.
fn pure<A: 'a>(a: A) -> Self::F<A>;
fn pure<A: 'a + Send>(a: A) -> Self::F<A>;
}
/// Part of [`Applicative`] responsible for Haskell's sequential application `<*>`.
pub trait ApplicativeSeq<'a>: Functor<'a> {
/// Equivalent of Haskell's `<*>`.
fn seq<A: 'a, B: 'a>(ff: Self::F<impl 'a + FnOnce(A) -> B>, fa: Self::F<A>) -> Self::F<B>;
fn seq<A: 'a + Send, B: 'a + Send>(
ff: Self::F<impl 'a + Send + FnOnce(A) -> B>,
fa: Self::F<A>,
) -> Self::F<B>;
}
/// Part of [`Applicative`] responsible for Haskell's result combination `listA2`.
pub trait ApplicativeLA2<'a>: Functor<'a> {
/// Equivalent of Haskell's `listA2`.
fn la2<A: 'a, B: 'a, C: 'a>(
fn la2<A: 'a + Send, B: 'a + Send, C: 'a + Send>(
fa: Self::F<A>,
fb: Self::F<B>,
f: impl 'a + FnOnce(A, B) -> C,
f: impl 'a + Send + FnOnce(A, B) -> C,
) -> Self::F<C>;
}
/// Part of [`Applicative`] responsible for Rust-style result combination, specifically for tuples.
pub trait ApplicativeTuple<'a>: Functor<'a> {
/// Similar to Haskell's `listA2` but with [Iterator::collect]-ish semantics.
fn tuple<A: 'a, B: 'a>(fab: (Self::F<A>, Self::F<B>)) -> Self::F<(A, B)>;
fn tuple<A: 'a + Send, B: 'a + Send>(fab: (Self::F<A>, Self::F<B>)) -> Self::F<(A, B)>;
}
/// Equivalent of Haskell's `Applicative`.
@ -92,12 +98,12 @@ pub trait Applicative<'a>:
Pure<'a> + ApplicativeSeq<'a> + ApplicativeLA2<'a> + ApplicativeTuple<'a> + ApplicativeSelect<'a>
{
/// Equivalent of Haskell's `*>`/`>>`.
fn discard_first<A: 'a, B: 'a>(fa: Self::F<A>, fb: Self::F<B>) -> Self::F<B> {
fn discard_first<A: 'a + Send, B: 'a + Send>(fa: Self::F<A>, fb: Self::F<B>) -> Self::F<B> {
Self::seq(Self::replace(fa, |b| b), fb)
}
/// Equivalent of Haskell's `<*`.
fn discard_second<A: 'a, B: 'a>(fa: Self::F<A>, fb: Self::F<B>) -> Self::F<A> {
fn discard_second<A: 'a + Send, B: 'a + Send>(fa: Self::F<A>, fb: Self::F<B>) -> Self::F<A> {
Self::la2(fa, fb, |a, _| a)
}
}
@ -109,7 +115,10 @@ pub trait Monad<'a>: Applicative<'a> {
/// Equivalent of Haskell's `>==`.
/// Due to Rust limitations, it's not a `function->function` conversion.
/// For that see [`derivations::bind`].
fn bind<A: 'a, B: 'a>(fa: Self::F<A>, f: impl 'a + FnOnce(A) -> Self::F<B>) -> Self::F<B>;
fn bind<A: 'a + Send, B: 'a + Send>(
fa: Self::F<A>,
f: impl 'a + Send + FnOnce(A) -> Self::F<B>,
) -> Self::F<B>;
/// Included for optimisation and clarity.
/// Generally, [`Monad::bind`] should be enough implement it.
@ -117,10 +126,10 @@ pub trait Monad<'a>: Applicative<'a> {
/// On practice, you generally shouldn't be using [`Monad::bind`]/[`Pure::pure`]/[`Functor::fmap`] here.
///
/// [`StacklessInstance::iterate`]: instances::stackless::StacklessInstance::iterate
fn iterate<B: 'a>(f: impl Iterative<'a, T = Self, B = B>) -> Self::F<B>;
fn iterate<B: 'a + Send>(f: impl Iterative<'a, T = Self, B = B>) -> Self::F<B>;
/// Equivalent of Haskell's `join`.
fn join<A: 'a>(ffa: Self::F<Self::F<A>>) -> Self::F<A> {
fn join<A: 'a + Send>(ffa: Self::F<Self::F<A>>) -> Self::F<A> {
Self::bind(ffa, |fa| fa)
}
}

View File

@ -1,6 +1,6 @@
use super::*;
pub enum Selected<'a, A: 'a, B: 'a, T: ?Sized + WeakFunctor<'a>> {
pub enum Selected<'a, A: 'a + Send, B: 'a + Send, T: ?Sized + WeakFunctor<'a>> {
A(A, T::F<B>),
B(T::F<A>, B),
}
@ -10,17 +10,20 @@ pub type SelectedWrapped<'a, A, B, T> = Wrap<'a, Selected<'a, A, B, T>, T>;
/// Part of [`Applicative`] responsible for choosing the first value.
pub trait ApplicativeSelect<'a>: Functor<'a> {
fn select<A: 'a, B: 'a>(fa: Self::F<A>, fb: Self::F<B>) -> SelectedWrapped<'a, A, B, Self> {
fn select<A: 'a + Send, B: 'a + Send>(
fa: Self::F<A>,
fb: Self::F<B>,
) -> SelectedWrapped<'a, A, B, Self> {
Self::fmap(fa, |a| Selected::A(a, fb))
}
}
pub trait ApplicativeSelectExt<'a>: ApplicativeSelect<'a> {
/// Shorthand for [`Functor::fmap`]&#8728;[`ApplicativeSelect::select`].
fn select_map<A: 'a, B: 'a, C: 'a>(
fn select_map<A: 'a + Send, B: 'a + Send, C: 'a + Send>(
fa: Self::F<A>,
fb: Self::F<B>,
f: impl 'a + FnOnce(Selected<'a, A, B, Self>) -> C,
f: impl 'a + Send + FnOnce(Selected<'a, A, B, Self>) -> C,
) -> Self::F<C> {
Self::fmap(Self::select(fa, fb), f)
}

View File

@ -2,28 +2,31 @@ use super::{fail::*, *};
pub type WrapC<'a, A, Ctx> = Wrap<'a, A, <Ctx as FunctorContext<'a>>::T>;
pub trait FunctorContext<'a>: 'a {
pub trait FunctorContext<'a>: 'a + Send {
type T: WeakFunctor<'a>;
}
pub trait FunctorContextExt<'a>: FunctorContext<'a> {
fn fmap<A: 'a, B: 'a>(fa: WrapC<'a, A, Self>, f: impl 'a + FnOnce(A) -> B) -> WrapC<'a, B, Self>
fn fmap<A: 'a + Send, B: 'a + Send>(
fa: WrapC<'a, A, Self>,
f: impl 'a + Send + FnOnce(A) -> B,
) -> WrapC<'a, B, Self>
where
Self::T: Functor<'a>,
{
<Self::T as Functor>::fmap(fa, f)
}
fn pure<A: 'a>(a: A) -> WrapC<'a, A, Self>
fn pure<A: 'a + Send>(a: A) -> WrapC<'a, A, Self>
where
Self::T: Pure<'a>,
{
<Self::T as Pure>::pure(a)
}
fn bind<A: 'a, B: 'a>(
fn bind<A: 'a + Send, B: 'a + Send>(
fa: WrapC<'a, A, Self>,
f: impl 'a + FnOnce(A) -> WrapC<'a, B, Self>,
f: impl 'a + Send + FnOnce(A) -> WrapC<'a, B, Self>,
) -> WrapC<'a, B, Self>
where
Self::T: Monad<'a>,
@ -31,7 +34,7 @@ pub trait FunctorContextExt<'a>: FunctorContext<'a> {
<Self::T as Monad>::bind(fa, f)
}
fn fail<A: 'a, E: 'a>(e: E) -> WrapC<'a, A, Self>
fn fail<A: 'a + Send, E: 'a + Send>(e: E) -> WrapC<'a, A, Self>
where
Self::T: Fail<'a, E>,
{
@ -58,12 +61,16 @@ pub type FallibleWrapped<'a, Ctx, A, E> = Wrap<'a, A, FallibleMonad<'a, Ctx, E>>
/// this is the preferred way to switch between [WrapC] and [FallibleWrapped].
pub trait FallibleCtxExt<'a>: FallibleCtx<'a> {
/// Convert a fallible wrapped into a wrapped result.
fn unstuff<A: 'a, E: 'a>(wa: FallibleWrapped<'a, Self, A, E>) -> WrapC<'a, Result<A, E>, Self> {
fn unstuff<A: 'a + Send, E: 'a + Send>(
wa: FallibleWrapped<'a, Self, A, E>,
) -> WrapC<'a, Result<A, E>, Self> {
Self::Fallible::unstuff(wa)
}
/// Convert a wrapped result into a fallible wrapped.
fn stuff<A: 'a, E: 'a>(fa: WrapC<'a, Result<A, E>, Self>) -> FallibleWrapped<'a, Self, A, E> {
fn stuff<A: 'a + Send, E: 'a + Send>(
fa: WrapC<'a, Result<A, E>, Self>,
) -> FallibleWrapped<'a, Self, A, E> {
Self::Fallible::stuff(fa)
}
}

View File

@ -6,14 +6,14 @@ use super::{weakfunctorany::WeakFunctorAny, Functor, Pure, WeakFunctor, Wrap};
pub(super) struct ControlFlowInstance<C>(ControlFlow<(), C>);
impl<C> WeakFunctorAny for ControlFlowInstance<C> {
type FAny<'a, A: 'a> = ControlFlow<A, C>
impl<C: Send> WeakFunctorAny for ControlFlowInstance<C> {
type FAny<'a, A: 'a + Send> = ControlFlow<A, C>
where
Self: 'a;
}
impl<'a, C: 'a> Functor<'a> for ControlFlowInstance<C> {
fn fmap<A: 'a, B: 'a>(fa: Self::F<A>, f: impl 'a + FnOnce(A) -> B) -> Self::F<B> {
impl<'a, C: 'a + Send> Functor<'a> for ControlFlowInstance<C> {
fn fmap<A: 'a + Send, B: 'a + Send>(fa: Self::F<A>, f: impl 'a + FnOnce(A) -> B) -> Self::F<B> {
match fa {
ControlFlow::Continue(c) => ControlFlow::Continue(c),
ControlFlow::Break(a) => ControlFlow::Break(f(a)),
@ -21,24 +21,34 @@ impl<'a, C: 'a> Functor<'a> for ControlFlowInstance<C> {
}
}
impl<'a, C: 'a> Pure<'a> for ControlFlowInstance<C> {
fn pure<A: 'a>(a: A) -> Self::F<A> {
impl<'a, C: 'a + Send> Pure<'a> for ControlFlowInstance<C> {
fn pure<A: 'a + Send>(a: A) -> Self::F<A> {
ControlFlow::Break(a)
}
}
pub struct BindableMut<T: ?Sized, A, B, F>(A, F, PhantomData<B>, PhantomData<T>);
impl<'a, T: ?Sized + Functor<'a>, A: 'a, B: 'a, F: 'a + FnMut(A) -> T::F<ControlFlow<B, A>>>
BindableMut<T, A, B, F>
impl<
'a,
T: ?Sized + Functor<'a>,
A: 'a + Send,
B: 'a + Send,
F: 'a + Send + FnMut(A) -> T::F<ControlFlow<B, A>>,
> BindableMut<T, A, B, F>
{
pub fn new(a: A, f: F) -> Self {
BindableMut(a, f, PhantomData, PhantomData)
}
}
impl<'a, T: ?Sized + Functor<'a>, A: 'a, B: 'a, F: 'a + FnMut(A) -> T::F<ControlFlow<B, A>>>
Iterative<'a> for BindableMut<T, A, B, F>
impl<
'a,
T: ?Sized + Functor<'a>,
A: 'a + Send,
B: 'a + Send,
F: 'a + Send + FnMut(A) -> T::F<ControlFlow<B, A>>,
> Iterative<'a> for BindableMut<T, A, B, F>
{
type B = B;
type T = T;
@ -58,9 +68,9 @@ pub type IterativeWrapped<'a, F> =
/// Value passed to [`Monad::iterate`].
///
/// [`Monad::iterate`]: super::Monad::iterate
pub trait Iterative<'a>: 'a + Sized {
pub trait Iterative<'a>: 'a + Send + Sized {
/// [`ControlFlow::Break`].
type B: 'a;
type B: 'a + Send;
/// Corresponding [`WeakFunctor`].
type T: ?Sized + WeakFunctor<'a>;
/// Get next state.

View File

@ -3,22 +3,22 @@
use super::*;
/// Equivalent of Haskell's `fmap`. `function-function` equivalent of [Functor::fmap].
pub fn fmap<'a, T: Functor<'a>, A: 'a, B: 'a>(
f: impl 'a + FnOnce(A) -> B,
pub fn fmap<'a, T: Functor<'a>, A: 'a + Send, B: 'a + Send>(
f: impl 'a + Send + FnOnce(A) -> B,
) -> impl FnOnce(Wrap<'a, A, T>) -> Wrap<'a, B, T> {
move |fa| T::fmap(fa, f)
}
/// Equivalent of Haskell's `fmap`. `function-function` equivalent of [Monad::bind].
pub fn bind<'a, T: Monad<'a>, A: 'a, B: 'a>(
f: impl 'a + FnOnce(A) -> T::F<B>,
pub fn bind<'a, T: Monad<'a>, A: 'a + Send, B: 'a + Send>(
f: impl 'a + Send + FnOnce(A) -> T::F<B>,
) -> impl FnOnce(Wrap<'a, A, T>) -> Wrap<'a, B, T> {
move |fa| T::bind(fa, f)
}
pub trait ApplicativeLA2ViaSeq<'a>: ApplicativeSeq<'a> {
fn _la2_via_seq<A: 'a, B: 'a, C: 'a>(
f: impl 'a + FnOnce(A, B) -> C,
fn _la2_via_seq<A: 'a + Send, B: 'a + Send, C: 'a + Send>(
f: impl 'a + Send + FnOnce(A, B) -> C,
fa: Self::F<A>,
fb: Self::F<B>,
) -> Self::F<C> {
@ -29,8 +29,8 @@ pub trait ApplicativeLA2ViaSeq<'a>: ApplicativeSeq<'a> {
impl<'a, T: ApplicativeSeq<'a>> ApplicativeLA2ViaSeq<'a> for T {}
pub trait ApplicativeSeqViaLA2<'a>: ApplicativeLA2<'a> {
fn _seq_via_la2<A: 'a, B: 'a>(
ff: Self::F<impl 'a + FnOnce(A) -> B>,
fn _seq_via_la2<A: 'a + Send, B: 'a + Send>(
ff: Self::F<impl 'a + Send + FnOnce(A) -> B>,
fa: Self::F<A>,
) -> Self::F<B> {
Self::la2(ff, fa, |f, a| f(a))
@ -40,7 +40,9 @@ pub trait ApplicativeSeqViaLA2<'a>: ApplicativeLA2<'a> {
impl<'a, T: ApplicativeLA2<'a>> ApplicativeSeqViaLA2<'a> for T {}
pub trait ApplicativeTupleViaLA2<'a>: ApplicativeLA2<'a> {
fn _tuple_via_la2<A: 'a, B: 'a>((fa, fb): (Self::F<A>, Self::F<B>)) -> Self::F<(A, B)> {
fn _tuple_via_la2<A: 'a + Send, B: 'a + Send>(
(fa, fb): (Self::F<A>, Self::F<B>),
) -> Self::F<(A, B)> {
Self::la2(fa, fb, |a, b| (a, b))
}
}

View File

@ -5,17 +5,17 @@ pub trait MonadExt<'a>: Monad<'a> {
/// Reasoning for this method existing at all is that
/// most usecases are better modelled with [`FnMut`]
/// rather than some dedicated state type.
fn iterate_mut<A: 'a, B: 'a>(
fn iterate_mut<A: 'a + Send, B: 'a + Send>(
a: A,
f: impl 'a + FnMut(A) -> Self::F<ControlFlow<B, A>>,
f: impl 'a + Send + FnMut(A) -> Self::F<ControlFlow<B, A>>,
) -> Self::F<B> {
Self::iterate(BindableMut::new(a, f))
}
fn bind2<A: 'a, B: 'a, C: 'a>(
fn bind2<A: 'a + Send, B: 'a + Send, C: 'a + Send>(
fa: Self::F<A>,
fb: Self::F<B>,
f: impl 'a + FnOnce(A, B) -> Self::F<C>,
f: impl 'a + Send + FnOnce(A, B) -> Self::F<C>,
) -> Self::F<C> {
Self::join(Self::la2(fa, fb, f))
}

View File

@ -1,44 +1,46 @@
use super::*;
/// Part of [`MonadFail`] responsible for Haskell's `fail`.
pub trait Fail<'a, E: 'a>: WeakFunctor<'a> {
pub trait Fail<'a, E: 'a + Send>: WeakFunctor<'a> {
/// Equivalent of Haskell's `fail`.
fn fail<A: 'a>(e: E) -> Self::F<A>;
fn fail<A: 'a + Send>(e: E) -> Self::F<A>;
}
/// Equivalent of Haskell's `MonadFail`. Auto-implemented for all [`Fail`]`+`[`Monad`].
///
/// <https://hackage.haskell.org/package/base-4.18.0.0/docs/Control-Monad.html>
pub trait MonadFail<'a, E: 'a>: Monad<'a> + Fail<'a, E> {}
pub trait MonadFail<'a, E: 'a + Send>: Monad<'a> + Fail<'a, E> {}
impl<'a, E: 'a, T: Monad<'a> + Fail<'a, E>> MonadFail<'a, E> for T {}
impl<'a, E: 'a + Send, T: Monad<'a> + Fail<'a, E>> MonadFail<'a, E> for T {}
/// Represents a (collection of) [Monad]\(s) that can hold any type of error.
pub trait MonadFailAny<'a>: 'a {
pub trait MonadFailAny<'a>: 'a + Send {
/// [`MonadFail`] for a specific error type.
type W<E>: MonadFail<'a, E>
where
E: 'a;
type W<E: 'a + Send>: MonadFail<'a, E>;
/// Associated infallible [`Monad`].
type T: Monad<'a>;
fn unstuff<A: 'a, E: 'a>(wa: WrapE<'a, A, E, Self>) -> Wrap<'a, Result<A, E>, Self::T>;
fn unstuff<A: 'a + Send, E: 'a + Send>(
wa: WrapE<'a, A, E, Self>,
) -> Wrap<'a, Result<A, E>, Self::T>;
fn stuff<A: 'a, E: 'a>(fa: Wrap<'a, Result<A, E>, Self::T>) -> WrapE<'a, A, E, Self>;
fn stuff<A: 'a + Send, E: 'a + Send>(
fa: Wrap<'a, Result<A, E>, Self::T>,
) -> WrapE<'a, A, E, Self>;
/// Equivalent of [`Result::map_err`].
fn map_err<A: 'a, E0: 'a, E1: 'a>(
fn map_err<A: 'a + Send, E0: 'a + Send, E1: 'a + Send>(
wa: WrapE<'a, A, E0, Self>,
f: impl 'a + FnOnce(E0) -> E1,
f: impl 'a + Send + FnOnce(E0) -> E1,
) -> WrapE<'a, A, E1, Self> {
Self::bind_err(wa, |e0| Self::fail(f(e0)))
}
/// Equivalent of `catch`/`except`. To inject errors on success, see [`MonadFailAny::bind`].
fn bind_err<A: 'a, E0: 'a, E1: 'a>(
fn bind_err<A: 'a + Send, E0: 'a + Send, E1: 'a + Send>(
wa: WrapE<'a, A, E0, Self>,
f: impl 'a + FnOnce(E0) -> WrapE<'a, A, E1, Self>,
f: impl 'a + Send + FnOnce(E0) -> WrapE<'a, A, E1, Self>,
) -> WrapE<'a, A, E1, Self> {
Self::bind(wa, |result| match result {
Ok(a) => Self::pure(a),
@ -51,9 +53,9 @@ pub trait MonadFailAny<'a>: 'a {
///
/// Note: Reasonably it is expected to lack fail semantics for the underlying result.
/// Therefore the default implementation descends into the non-fail monad [`MonadFailAny::T`].
fn bind<A: 'a, B: 'a, E0: 'a, E1: 'a>(
fn bind<A: 'a + Send, B: 'a + Send, E0: 'a + Send, E1: 'a + Send>(
wa: WrapE<'a, A, E0, Self>,
f: impl 'a + FnOnce(Result<A, E0>) -> WrapE<'a, B, E1, Self>,
f: impl 'a + Send + FnOnce(Result<A, E0>) -> WrapE<'a, B, E1, Self>,
) -> WrapE<'a, B, E1, Self> {
Self::stuff(<Self::T as Monad>::bind(Self::unstuff(wa), |result| {
Self::unstuff(f(result))
@ -63,7 +65,7 @@ pub trait MonadFailAny<'a>: 'a {
/// Equivalent of [`Monad::join`], flattening the errors.
///
/// Note: default implementation doesn't depend on [`Monad::join`].
fn join<A: 'a, E0: 'a, E1: 'a>(
fn join<A: 'a + Send, E0: 'a + Send, E1: 'a + Send>(
wwa: WrapE<'a, WrapE<'a, A, E0, Self>, E1, Self>,
) -> WrapE<'a, A, Result<E0, E1>, Self> {
Self::bind(wwa, |result| match result {
@ -73,7 +75,7 @@ pub trait MonadFailAny<'a>: 'a {
}
/// Lift the error.
fn rotate_out<A: 'a, E0: 'a, E1: 'a>(
fn rotate_out<A: 'a + Send, E0: 'a + Send, E1: 'a + Send>(
wa: WrapE<'a, Result<A, E1>, E0, Self>,
) -> WrapE<'a, A, Result<E1, E0>, Self> {
<Self::W<Result<E1, E0>> as Monad>::bind(Self::map_err(wa, Err), |fa| match fa {
@ -86,11 +88,11 @@ pub trait MonadFailAny<'a>: 'a {
pub type WrapE<'a, A, E, Fallible> = Wrap<'a, A, <Fallible as MonadFailAny<'a>>::W<E>>;
pub trait MonadFailAnyExt<'a>: MonadFailAny<'a> {
fn pure<E: 'a, A: 'a>(a: A) -> WrapE<'a, A, E, Self> {
fn pure<E: 'a + Send, A: 'a + Send>(a: A) -> WrapE<'a, A, E, Self> {
<Self::W<E> as Pure>::pure(a)
}
fn fail<E: 'a, A: 'a>(e: E) -> WrapE<'a, A, E, Self> {
fn fail<E: 'a + Send, A: 'a + Send>(e: E) -> WrapE<'a, A, E, Self> {
<Self::W<E> as Fail<E>>::fail(e)
}
}

View File

@ -14,25 +14,28 @@ use crate::func::class_prelude::*;
pub struct CompositionInstance<U, V>(U, V);
impl<'a, U: WeakFunctor<'a>, V: WeakFunctor<'a>> WeakFunctor<'a> for CompositionInstance<U, V> {
type F<A: 'a> = U::F<V::F<A>>;
type F<A: 'a + Send> = U::F<V::F<A>>;
}
impl<'a, U: Functor<'a>, V: Functor<'a>> Functor<'a> for CompositionInstance<U, V> {
fn fmap<A: 'a, B: 'a>(fa: Self::F<A>, f: impl 'a + FnOnce(A) -> B) -> Self::F<B> {
fn fmap<A: 'a + Send, B: 'a + Send>(
fa: Self::F<A>,
f: impl 'a + Send + FnOnce(A) -> B,
) -> Self::F<B> {
U::fmap(fa, |ua| V::fmap(ua, f))
}
fn replace<A: 'a, B: 'a>(fa: Self::F<A>, b: B) -> Self::F<B> {
fn replace<A: 'a + Send, B: 'a + Send>(fa: Self::F<A>, b: B) -> Self::F<B> {
U::fmap(fa, |ua| V::replace(ua, b))
}
fn void<A: 'a>(fa: Self::F<A>) -> Self::F<()> {
fn void<A: 'a + Send>(fa: Self::F<A>) -> Self::F<()> {
U::fmap(fa, |ua| V::void(ua))
}
}
impl<'a, U: Pure<'a>, V: Pure<'a>> Pure<'a> for CompositionInstance<U, V> {
fn pure<A: 'a>(a: A) -> Self::F<A> {
fn pure<A: 'a + Send>(a: A) -> Self::F<A> {
U::pure(V::pure(a))
}
}
@ -41,7 +44,10 @@ impl<'a, U: Pure<'a>, V: Pure<'a>> Pure<'a> for CompositionInstance<U, V> {
impl<'a, U: ApplicativeLA2<'a>, V: ApplicativeSeq<'a>> ApplicativeSeq<'a>
for CompositionInstance<U, V>
{
fn seq<A: 'a, B: 'a>(ff: Self::F<impl 'a + FnOnce(A) -> B>, fa: Self::F<A>) -> Self::F<B> {
fn seq<A: 'a + Send, B: 'a + Send>(
ff: Self::F<impl 'a + Send + FnOnce(A) -> B>,
fa: Self::F<A>,
) -> Self::F<B> {
U::la2(ff, fa, V::seq)
}
}
@ -49,10 +55,10 @@ impl<'a, U: ApplicativeLA2<'a>, V: ApplicativeSeq<'a>> ApplicativeSeq<'a>
impl<'a, U: ApplicativeLA2<'a>, V: ApplicativeLA2<'a>> ApplicativeLA2<'a>
for CompositionInstance<U, V>
{
fn la2<A: 'a, B: 'a, C: 'a>(
fn la2<A: 'a + Send, B: 'a + Send, C: 'a + Send>(
fa: Self::F<A>,
fb: Self::F<B>,
f: impl 'a + FnOnce(A, B) -> C,
f: impl 'a + Send + FnOnce(A, B) -> C,
) -> Self::F<C> {
U::la2(fa, fb, |ua, ub| V::la2(ua, ub, f))
}
@ -61,7 +67,7 @@ impl<'a, U: ApplicativeLA2<'a>, V: ApplicativeLA2<'a>> ApplicativeLA2<'a>
impl<'a, U: ApplicativeTuple<'a>, V: ApplicativeTuple<'a>> ApplicativeTuple<'a>
for CompositionInstance<U, V>
{
fn tuple<A: 'a, B: 'a>(fab: (Self::F<A>, Self::F<B>)) -> Self::F<(A, B)> {
fn tuple<A: 'a + Send, B: 'a + Send>(fab: (Self::F<A>, Self::F<B>)) -> Self::F<(A, B)> {
U::fmap(U::tuple(fab), V::tuple)
}
}
@ -70,7 +76,10 @@ impl<'a, U: ApplicativeTuple<'a>, V: ApplicativeTuple<'a>> ApplicativeTuple<'a>
impl<'a, U: ApplicativeSelect<'a>, V: Functor<'a>> ApplicativeSelect<'a>
for CompositionInstance<U, V>
{
fn select<A: 'a, B: 'a>(fa: Self::F<A>, fb: Self::F<B>) -> SelectedWrapped<'a, A, B, Self> {
fn select<A: 'a + Send, B: 'a + Send>(
fa: Self::F<A>,
fb: Self::F<B>,
) -> SelectedWrapped<'a, A, B, Self> {
U::fmap(U::select(fa, fb), |selected| match selected {
Selected::A(ua, fb) => V::fmap(ua, |a| Selected::A(a, fb)),
Selected::B(fa, ub) => V::fmap(ub, |b| Selected::B(fa, b)),
@ -79,21 +88,24 @@ impl<'a, U: ApplicativeSelect<'a>, V: Functor<'a>> ApplicativeSelect<'a>
}
impl<'a, U: Applicative<'a>, V: Applicative<'a>> Applicative<'a> for CompositionInstance<U, V> {
fn discard_first<A: 'a, B: 'a>(fa: Self::F<A>, fb: Self::F<B>) -> Self::F<B> {
fn discard_first<A: 'a + Send, B: 'a + Send>(fa: Self::F<A>, fb: Self::F<B>) -> Self::F<B> {
U::la2(fa, fb, V::discard_first)
}
fn discard_second<A: 'a, B: 'a>(fa: Self::F<A>, fb: Self::F<B>) -> Self::F<A> {
fn discard_second<A: 'a + Send, B: 'a + Send>(fa: Self::F<A>, fb: Self::F<B>) -> Self::F<A> {
U::la2(fa, fb, V::discard_second)
}
}
impl<'a, U: Monad<'a>, V: Monad<'a> + LocalFunctor<'a>> Monad<'a> for CompositionInstance<U, V> {
fn bind<A: 'a, B: 'a>(fa: Self::F<A>, f: impl 'a + FnOnce(A) -> Self::F<B>) -> Self::F<B> {
fn bind<A: 'a + Send, B: 'a + Send>(
fa: Self::F<A>,
f: impl 'a + Send + FnOnce(A) -> Self::F<B>,
) -> Self::F<B> {
U::bind(fa, |ua| U::fmap(V::stuff::<_, U>(V::fmap(ua, f)), V::join))
}
fn iterate<B: 'a>(f: impl Iterative<'a, T = Self, B = B>) -> Self::F<B> {
fn iterate<B: 'a + Send>(f: impl Iterative<'a, T = Self, B = B>) -> Self::F<B> {
U::iterate(ComposedIterative(f))
}
@ -104,7 +116,7 @@ impl<'a, U: Monad<'a>, V: Monad<'a> + LocalFunctor<'a>> Monad<'a> for Compositio
/// U U V V A
/// U V A
/// ```
fn join<A: 'a>(ffa: Self::F<Self::F<A>>) -> Self::F<A> {
fn join<A: 'a + Send>(ffa: Self::F<Self::F<A>>) -> Self::F<A> {
U::join(U::fmap(ffa, |ufa| U::fmap(V::stuff::<_, U>(ufa), V::join)))
}
}
@ -129,10 +141,10 @@ where
}
/// Note: fails in the inner instance not outer.
impl<'a, E: 'a, U: Monad<'a>, V: Fail<'a, E> + LocalFunctor<'a>> Fail<'a, E>
impl<'a, E: 'a + Send, U: Monad<'a>, V: Fail<'a, E> + LocalFunctor<'a>> Fail<'a, E>
for CompositionInstance<U, V>
{
fn fail<A: 'a>(e: E) -> Self::F<A> {
fn fail<A: 'a + Send>(e: E) -> Self::F<A> {
U::pure(V::fail(e))
}
}
@ -140,11 +152,13 @@ impl<'a, E: 'a, U: Monad<'a>, V: Fail<'a, E> + LocalFunctor<'a>> Fail<'a, E>
impl<'a, U: LocalFunctor<'a> + Functor<'a>, V: LocalFunctor<'a>> LocalFunctor<'a>
for CompositionInstance<U, V>
{
fn unstuff<A: 'a, B: 'a>(state: Self::F<ControlFlow<B, A>>) -> ControlFlow<Self::F<B>, A> {
fn unstuff<A: 'a + Send, B: 'a + Send>(
state: Self::F<ControlFlow<B, A>>,
) -> ControlFlow<Self::F<B>, A> {
U::unstuff(U::fmap(state, V::unstuff))
}
fn stuff<A: 'a, T: Pure<'a>>(fa: Self::F<T::F<A>>) -> T::F<Self::F<A>> {
fn stuff<A: 'a + Send, T: Pure<'a>>(fa: Self::F<T::F<A>>) -> T::F<Self::F<A>> {
U::stuff::<_, T>(U::fmap(fa, V::stuff::<_, T>))
}
}
@ -152,13 +166,13 @@ impl<'a, U: LocalFunctor<'a> + Functor<'a>, V: LocalFunctor<'a>> LocalFunctor<'a
impl<'a, U: SharedFunctor<'a> + Functor<'a>, V: SharedFunctor<'a>> SharedFunctor<'a>
for CompositionInstance<U, V>
{
type Shared<A: 'a + Clone> = U::Shared<V::Shared<A>>;
type Shared<A: 'a + Send + Sync + Clone> = U::Shared<V::Shared<A>>;
fn share<A: 'a + Clone>(fa: Self::F<A>) -> Self::Shared<A> {
fn share<A: 'a + Send + Sync + Clone>(fa: Self::F<A>) -> Self::Shared<A> {
U::share(U::fmap(fa, V::share))
}
fn unshare<A: 'a + Clone>(sa: Self::Shared<A>) -> Self::F<A> {
fn unshare<A: 'a + Send + Sync + Clone>(sa: Self::Shared<A>) -> Self::F<A> {
U::fmap(U::unshare(sa), V::unshare)
}
}

View File

@ -10,7 +10,7 @@
use crate::func::class_prelude::*;
/// Metadata type.
pub trait Effect {
pub trait Effect: Send {
/// Used in [`Pure::pure`].
fn e_pure() -> Self;
@ -37,24 +37,43 @@ impl<A, E: Effect> WithEffect<A, E> {
}
}
#[derive(SharedFunctorAny)]
pub struct EffectInstance<E>(E);
pub struct EffectInstance<E: Send>(E);
impl<E> WeakFunctorAny for EffectInstance<E> {
type FAny<'a, A: 'a> = WithEffect<A, E>
impl<E: Send + Sync + Clone> SharedFunctorAny for EffectInstance<E> {
type SharedAny<'a, A: 'a + Send + Sync + Clone> = Self::FAny<'a, A>
where
Self: 'a;
fn share<'a, A: 'a + Send + Sync + Clone>(fa: Self::FAny<'a, A>) -> Self::SharedAny<'a, A>
where
Self: 'a,
{
fa
}
fn unshare<'a, A: 'a + Send + Sync + Clone>(sa: Self::SharedAny<'a, A>) -> Self::FAny<'a, A>
where
Self: 'a,
{
sa
}
}
impl<E: Send> WeakFunctorAny for EffectInstance<E> {
type FAny<'a, A: 'a + Send> = WithEffect<A, E>
where
Self: 'a;
}
impl<'a, E: 'a> Functor<'a> for EffectInstance<E> {
fn fmap<A: 'a, B: 'a>(fa: Self::F<A>, f: impl 'a + FnOnce(A) -> B) -> Self::F<B> {
impl<'a, E: 'a + Send> Functor<'a> for EffectInstance<E> {
fn fmap<A: 'a + Send, B: 'a + Send>(fa: Self::F<A>, f: impl 'a + FnOnce(A) -> B) -> Self::F<B> {
WithEffect {
value: f(fa.value),
effect: fa.effect,
}
}
fn replace<A: 'a, B: 'a>(fa: Self::F<A>, b: B) -> Self::F<B> {
fn replace<A: 'a + Send, B: 'a + Send>(fa: Self::F<A>, b: B) -> Self::F<B> {
drop(fa.value);
WithEffect {
value: b,
@ -64,7 +83,7 @@ impl<'a, E: 'a> Functor<'a> for EffectInstance<E> {
}
impl<'a, E: 'a + Effect> Pure<'a> for EffectInstance<E> {
fn pure<A: 'a>(a: A) -> Self::F<A> {
fn pure<A: 'a + Send>(a: A) -> Self::F<A> {
WithEffect {
value: a,
effect: E::e_pure(),
@ -73,7 +92,10 @@ impl<'a, E: 'a + Effect> Pure<'a> for EffectInstance<E> {
}
impl<'a, E: 'a + Effect> ApplicativeSeq<'a> for EffectInstance<E> {
fn seq<A: 'a, B: 'a>(ff: Self::F<impl 'a + FnOnce(A) -> B>, fa: Self::F<A>) -> Self::F<B> {
fn seq<A: 'a + Send, B: 'a + Send>(
ff: Self::F<impl 'a + Send + FnOnce(A) -> B>,
fa: Self::F<A>,
) -> Self::F<B> {
WithEffect {
value: (ff.value)(fa.value),
effect: E::e_seq(ff.effect, fa.effect),
@ -82,10 +104,10 @@ impl<'a, E: 'a + Effect> ApplicativeSeq<'a> for EffectInstance<E> {
}
impl<'a, E: 'a + Effect> ApplicativeLA2<'a> for EffectInstance<E> {
fn la2<A: 'a, B: 'a, C: 'a>(
fn la2<A: 'a + Send, B: 'a + Send, C: 'a + Send>(
fa: Self::F<A>,
fb: Self::F<B>,
f: impl 'a + FnOnce(A, B) -> C,
f: impl 'a + Send + FnOnce(A, B) -> C,
) -> Self::F<C> {
WithEffect {
value: f(fa.value, fb.value),
@ -95,7 +117,7 @@ impl<'a, E: 'a + Effect> ApplicativeLA2<'a> for EffectInstance<E> {
}
impl<'a, E: 'a + Effect> ApplicativeTuple<'a> for EffectInstance<E> {
fn tuple<A: 'a, B: 'a>((fa, fb): (Self::F<A>, Self::F<B>)) -> Self::F<(A, B)> {
fn tuple<A: 'a + Send, B: 'a + Send>((fa, fb): (Self::F<A>, Self::F<B>)) -> Self::F<(A, B)> {
WithEffect {
value: (fa.value, fb.value),
effect: E::e_seq(fa.effect, fb.effect),
@ -106,7 +128,7 @@ impl<'a, E: 'a + Effect> ApplicativeTuple<'a> for EffectInstance<E> {
impl<'a, E: 'a + Effect> ApplicativeSelect<'a> for EffectInstance<E> {}
impl<'a, E: 'a + Effect> Applicative<'a> for EffectInstance<E> {
fn discard_first<A: 'a, B: 'a>(fa: Self::F<A>, fb: Self::F<B>) -> Self::F<B> {
fn discard_first<A: 'a + Send, B: 'a + Send>(fa: Self::F<A>, fb: Self::F<B>) -> Self::F<B> {
drop(fa.value);
WithEffect {
value: fb.value,
@ -114,7 +136,7 @@ impl<'a, E: 'a + Effect> Applicative<'a> for EffectInstance<E> {
}
}
fn discard_second<A: 'a, B: 'a>(fa: Self::F<A>, fb: Self::F<B>) -> Self::F<A> {
fn discard_second<A: 'a + Send, B: 'a + Send>(fa: Self::F<A>, fb: Self::F<B>) -> Self::F<A> {
drop(fb.value);
WithEffect {
value: fa.value,
@ -124,11 +146,14 @@ impl<'a, E: 'a + Effect> Applicative<'a> for EffectInstance<E> {
}
impl<'a, E: 'a + Effect> Monad<'a> for EffectInstance<E> {
fn bind<A: 'a, B: 'a>(fa: Self::F<A>, f: impl 'a + FnOnce(A) -> Self::F<B>) -> Self::F<B> {
fn bind<A: 'a + Send, B: 'a + Send>(
fa: Self::F<A>,
f: impl 'a + FnOnce(A) -> Self::F<B>,
) -> Self::F<B> {
f(fa.value).e_after(fa.effect)
}
fn iterate<B: 'a>(mut f: impl Iterative<'a, T = Self, B = B>) -> Self::F<B> {
fn iterate<B: 'a + Send>(mut f: impl Iterative<'a, T = Self, B = B>) -> Self::F<B> {
let mut effect = E::e_pure();
loop {
let fa = f.next();
@ -140,13 +165,13 @@ impl<'a, E: 'a + Effect> Monad<'a> for EffectInstance<E> {
}
}
fn join<A: 'a>(ffa: Self::F<Self::F<A>>) -> Self::F<A> {
fn join<A: 'a + Send>(ffa: Self::F<Self::F<A>>) -> Self::F<A> {
ffa.value.e_after(ffa.effect)
}
}
impl<'a, E: 'a> LocalFunctor<'a> for EffectInstance<E> {
fn stuff<A: 'a, T: Pure<'a>>(fa: Self::F<T::F<A>>) -> T::F<Self::F<A>> {
impl<'a, E: 'a + Send> LocalFunctor<'a> for EffectInstance<E> {
fn stuff<A: 'a + Send, T: Pure<'a>>(fa: Self::F<T::F<A>>) -> T::F<Self::F<A>> {
T::fmap(fa.value, |a| WithEffect {
value: a,
effect: fa.effect,

View File

@ -21,15 +21,18 @@ use crate::func::class_prelude::*;
pub struct FutureInstance;
impl WeakFunctorAny for FutureInstance {
type FAny<'a, A: 'a> = Pin<Box<dyn 'a + Future<Output = A>>>;
type FAny<'a, A: 'a + Send> = Pin<Box<dyn 'a + Send + Future<Output = A>>>;
}
impl<'a> Functor<'a> for FutureInstance {
fn fmap<A: 'a, B: 'a>(fa: Self::F<A>, f: impl 'a + FnOnce(A) -> B) -> Self::F<B> {
fn fmap<A: 'a + Send, B: 'a + Send>(
fa: Self::F<A>,
f: impl 'a + Send + FnOnce(A) -> B,
) -> Self::F<B> {
Box::pin(async { f(fa.await) })
}
fn replace<A: 'a, B: 'a>(fa: Self::F<A>, b: B) -> Self::F<B> {
fn replace<A: 'a + Send, B: 'a + Send>(fa: Self::F<A>, b: B) -> Self::F<B> {
Box::pin(async {
fa.await;
b
@ -38,13 +41,16 @@ impl<'a> Functor<'a> for FutureInstance {
}
impl<'a> Pure<'a> for FutureInstance {
fn pure<A: 'a>(a: A) -> Self::F<A> {
fn pure<A: 'a + Send>(a: A) -> Self::F<A> {
Box::pin(async { a })
}
}
impl<'a> ApplicativeSeq<'a> for FutureInstance {
fn seq<A: 'a, B: 'a>(ff: Self::F<impl 'a + FnOnce(A) -> B>, fa: Self::F<A>) -> Self::F<B> {
fn seq<A: 'a + Send, B: 'a + Send>(
ff: Self::F<impl 'a + Send + FnOnce(A) -> B>,
fa: Self::F<A>,
) -> Self::F<B> {
Box::pin(async {
let (f, a) = join!(ff, fa);
f(a)
@ -53,10 +59,10 @@ impl<'a> ApplicativeSeq<'a> for FutureInstance {
}
impl<'a> ApplicativeLA2<'a> for FutureInstance {
fn la2<A: 'a, B: 'a, C: 'a>(
fn la2<A: 'a + Send, B: 'a + Send, C: 'a + Send>(
fa: Self::F<A>,
fb: Self::F<B>,
f: impl 'a + FnOnce(A, B) -> C,
f: impl 'a + Send + FnOnce(A, B) -> C,
) -> Self::F<C> {
Box::pin(async {
let (a, b) = join!(fa, fb);
@ -66,13 +72,16 @@ impl<'a> ApplicativeLA2<'a> for FutureInstance {
}
impl<'a> ApplicativeTuple<'a> for FutureInstance {
fn tuple<A: 'a, B: 'a>((fa, fb): (Self::F<A>, Self::F<B>)) -> Self::F<(A, B)> {
fn tuple<A: 'a + Send, B: 'a + Send>((fa, fb): (Self::F<A>, Self::F<B>)) -> Self::F<(A, B)> {
Box::pin(join(fa, fb))
}
}
impl<'a> ApplicativeSelect<'a> for FutureInstance {
fn select<A: 'a, B: 'a>(fa: Self::F<A>, fb: Self::F<B>) -> SelectedWrapped<'a, A, B, Self> {
fn select<A: 'a + Send, B: 'a + Send>(
fa: Self::F<A>,
fb: Self::F<B>,
) -> SelectedWrapped<'a, A, B, Self> {
Box::pin(async {
match select(fa, fb).await {
Either::Left((a, fb)) => Selected::A(a, fb),
@ -83,21 +92,24 @@ impl<'a> ApplicativeSelect<'a> for FutureInstance {
}
impl<'a> Applicative<'a> for FutureInstance {
fn discard_first<A: 'a, B: 'a>(fa: Self::F<A>, fb: Self::F<B>) -> Self::F<B> {
fn discard_first<A: 'a + Send, B: 'a + Send>(fa: Self::F<A>, fb: Self::F<B>) -> Self::F<B> {
Box::pin(async { join!(fa, fb).1 })
}
fn discard_second<A: 'a, B: 'a>(fa: Self::F<A>, fb: Self::F<B>) -> Self::F<A> {
fn discard_second<A: 'a + Send, B: 'a + Send>(fa: Self::F<A>, fb: Self::F<B>) -> Self::F<A> {
Box::pin(async { join!(fa, fb).0 })
}
}
impl<'a> Monad<'a> for FutureInstance {
fn bind<A: 'a, B: 'a>(fa: Self::F<A>, f: impl 'a + FnOnce(A) -> Self::F<B>) -> Self::F<B> {
fn bind<A: 'a + Send, B: 'a + Send>(
fa: Self::F<A>,
f: impl 'a + Send + FnOnce(A) -> Self::F<B>,
) -> Self::F<B> {
Box::pin(async { f(fa.await).await })
}
fn iterate<B: 'a>(mut f: impl Iterative<'a, T = Self, B = B>) -> Self::F<B> {
fn iterate<B: 'a + Send>(mut f: impl Iterative<'a, T = Self, B = B>) -> Self::F<B> {
Box::pin(async move {
loop {
match f.next().await {
@ -108,19 +120,19 @@ impl<'a> Monad<'a> for FutureInstance {
})
}
fn join<A: 'a>(ffa: Self::F<Self::F<A>>) -> Self::F<A> {
fn join<A: 'a + Send>(ffa: Self::F<Self::F<A>>) -> Self::F<A> {
Box::pin(async { ffa.await.await })
}
}
impl<'a> SharedFunctor<'a> for FutureInstance {
type Shared<A: 'a + Clone> = Shared<Pin<Box<dyn 'a + Future<Output = A>>>>;
type Shared<A: 'a + Send + Sync + Clone> = Shared<Pin<Box<dyn 'a + Send + Future<Output = A>>>>;
fn share<A: 'a + Clone>(fa: Self::F<A>) -> Self::Shared<A> {
fn share<A: 'a + Send + Sync + Clone>(fa: Self::F<A>) -> Self::Shared<A> {
fa.shared()
}
fn unshare<A: 'a + Clone>(sa: Self::Shared<A>) -> Self::F<A> {
fn unshare<A: 'a + Send + Sync + Clone>(sa: Self::Shared<A>) -> Self::F<A> {
Box::pin(sa)
}
}

View File

@ -9,56 +9,60 @@
//!
//! [`stackless`]: super::stackless
use std::{cell::RefCell, rc::Rc};
use crate::func::class_prelude::*;
pub struct LazyInstance;
impl WeakFunctorAny for LazyInstance {
type FAny<'a, A: 'a> = Box<dyn 'a + FnOnce() -> A>;
type FAny<'a, A: 'a + Send> = Box<dyn 'a + Send + FnOnce() -> A>;
}
impl<'a> Functor<'a> for LazyInstance {
fn fmap<A: 'a, B: 'a>(fa: Self::F<A>, f: impl 'a + FnOnce(A) -> B) -> Self::F<B> {
fn fmap<A: 'a + Send, B: 'a + Send>(
fa: Self::F<A>,
f: impl 'a + Send + FnOnce(A) -> B,
) -> Self::F<B> {
Box::new(|| f(fa()))
}
fn replace<A: 'a, B: 'a>(fa: Self::F<A>, b: B) -> Self::F<B> {
fn replace<A: 'a + Send, B: 'a + Send>(fa: Self::F<A>, b: B) -> Self::F<B> {
drop(fa);
Box::new(|| b)
}
fn void<A: 'a>(fa: Self::F<A>) -> Self::F<()> {
fn void<A: 'a + Send>(fa: Self::F<A>) -> Self::F<()> {
drop(fa);
Box::new(|| ())
}
}
impl<'a> Pure<'a> for LazyInstance {
fn pure<A: 'a>(a: A) -> Self::F<A> {
fn pure<A: 'a + Send>(a: A) -> Self::F<A> {
Box::new(|| a)
}
}
impl<'a> ApplicativeSeq<'a> for LazyInstance {
fn seq<A: 'a, B: 'a>(ff: Self::F<impl 'a + FnOnce(A) -> B>, fa: Self::F<A>) -> Self::F<B> {
fn seq<A: 'a + Send, B: 'a + Send>(
ff: Self::F<impl 'a + Send + FnOnce(A) -> B>,
fa: Self::F<A>,
) -> Self::F<B> {
Box::new(|| ff()(fa()))
}
}
impl<'a> ApplicativeLA2<'a> for LazyInstance {
fn la2<A: 'a, B: 'a, C: 'a>(
fn la2<A: 'a + Send, B: 'a + Send, C: 'a + Send>(
fa: Self::F<A>,
fb: Self::F<B>,
f: impl 'a + FnOnce(A, B) -> C,
f: impl 'a + Send + FnOnce(A, B) -> C,
) -> Self::F<C> {
Box::new(|| f(fa(), fb()))
}
}
impl<'a> ApplicativeTuple<'a> for LazyInstance {
fn tuple<A: 'a, B: 'a>((fa, fb): (Self::F<A>, Self::F<B>)) -> Self::F<(A, B)> {
fn tuple<A: 'a + Send, B: 'a + Send>((fa, fb): (Self::F<A>, Self::F<B>)) -> Self::F<(A, B)> {
Box::new(|| (fa(), fb()))
}
}
@ -66,23 +70,26 @@ impl<'a> ApplicativeTuple<'a> for LazyInstance {
impl<'a> ApplicativeSelect<'a> for LazyInstance {}
impl<'a> Applicative<'a> for LazyInstance {
fn discard_first<A: 'a, B: 'a>(fa: Self::F<A>, fb: Self::F<B>) -> Self::F<B> {
fn discard_first<A: 'a + Send, B: 'a + Send>(fa: Self::F<A>, fb: Self::F<B>) -> Self::F<B> {
drop(fa);
fb
}
fn discard_second<A: 'a, B: 'a>(fa: Self::F<A>, fb: Self::F<B>) -> Self::F<A> {
fn discard_second<A: 'a + Send, B: 'a + Send>(fa: Self::F<A>, fb: Self::F<B>) -> Self::F<A> {
drop(fb);
fa
}
}
impl<'a> Monad<'a> for LazyInstance {
fn bind<A: 'a, B: 'a>(fa: Self::F<A>, f: impl 'a + FnOnce(A) -> Self::F<B>) -> Self::F<B> {
fn bind<A: 'a + Send, B: 'a + Send>(
fa: Self::F<A>,
f: impl 'a + Send + FnOnce(A) -> Self::F<B>,
) -> Self::F<B> {
Box::new(|| f(fa())())
}
fn iterate<B: 'a>(mut f: impl Iterative<'a, T = Self, B = B>) -> Self::F<B> {
fn iterate<B: 'a + Send>(mut f: impl Iterative<'a, T = Self, B = B>) -> Self::F<B> {
loop {
match f.next()() {
ControlFlow::Continue(next_f) => f = next_f,
@ -91,28 +98,7 @@ impl<'a> Monad<'a> for LazyInstance {
}
}
fn join<A: 'a>(ffa: Self::F<Self::F<A>>) -> Self::F<A> {
fn join<A: 'a + Send>(ffa: Self::F<Self::F<A>>) -> Self::F<A> {
Box::new(|| ffa()())
}
}
fn unshare<'a, A: 'a + Clone>(shared: &mut Option<Box<dyn 'a + FnOnce() -> A>>) -> A {
let a = shared.take().expect(
"cannot evaluate a missing shared lazy value. probably, the shared value depends on itself",
)();
let cloned = a.clone();
*shared = Some(Box::new(|| cloned));
a
}
impl<'a> SharedFunctor<'a> for LazyInstance {
type Shared<A: 'a + Clone> = Rc<RefCell<Option<Box<dyn 'a + FnOnce() -> A>>>>;
fn share<A: 'a + Clone>(fa: Self::F<A>) -> Self::Shared<A> {
Rc::new(RefCell::new(Some(fa)))
}
fn unshare<A: 'a + Clone>(sa: Self::Shared<A>) -> Self::F<A> {
Box::new(move || unshare(&mut *sa.borrow_mut()))
}
}

View File

@ -17,49 +17,55 @@ use crate::func::class_prelude::*;
pub struct OptionInstance;
impl WeakFunctorAny for OptionInstance {
type FAny<'a, A: 'a> = Option<A>;
type FAny<'a, A: 'a + Send> = Option<A>;
}
impl<'a> Functor<'a> for OptionInstance {
fn fmap<A: 'a, B: 'a>(fa: Self::F<A>, f: impl 'a + FnOnce(A) -> B) -> Self::F<B> {
fn fmap<A: 'a + Send, B: 'a + Send>(
fa: Self::F<A>,
f: impl 'a + Send + FnOnce(A) -> B,
) -> Self::F<B> {
fa.map(f)
}
fn replace<A: 'a, B: 'a>(fa: Self::F<A>, b: B) -> Self::F<B> {
fn replace<A: 'a + Send, B: 'a + Send>(fa: Self::F<A>, b: B) -> Self::F<B> {
fa?;
Self::pure(b)
}
fn void<A: 'a>(fa: Self::F<A>) -> Self::F<()> {
fn void<A: 'a + Send>(fa: Self::F<A>) -> Self::F<()> {
fa?;
Self::pure(())
}
}
impl<'a> Pure<'a> for OptionInstance {
fn pure<A: 'a>(a: A) -> Self::F<A> {
fn pure<A: 'a + Send>(a: A) -> Self::F<A> {
Some(a)
}
}
impl<'a> ApplicativeSeq<'a> for OptionInstance {
fn seq<A: 'a, B: 'a>(ff: Self::F<impl 'a + FnOnce(A) -> B>, fa: Self::F<A>) -> Self::F<B> {
fn seq<A: 'a + Send, B: 'a + Send>(
ff: Self::F<impl 'a + Send + FnOnce(A) -> B>,
fa: Self::F<A>,
) -> Self::F<B> {
Self::pure(ff?(fa?))
}
}
impl<'a> ApplicativeLA2<'a> for OptionInstance {
fn la2<A: 'a, B: 'a, C: 'a>(
fn la2<A: 'a + Send, B: 'a + Send, C: 'a + Send>(
fa: Self::F<A>,
fb: Self::F<B>,
f: impl 'a + FnOnce(A, B) -> C,
f: impl 'a + Send + FnOnce(A, B) -> C,
) -> Self::F<C> {
Self::pure(f(fa?, fb?))
}
}
impl<'a> ApplicativeTuple<'a> for OptionInstance {
fn tuple<A: 'a, B: 'a>((fa, fb): (Self::F<A>, Self::F<B>)) -> Self::F<(A, B)> {
fn tuple<A: 'a + Send, B: 'a + Send>((fa, fb): (Self::F<A>, Self::F<B>)) -> Self::F<(A, B)> {
Self::pure((fa?, fb?))
}
}
@ -67,23 +73,26 @@ impl<'a> ApplicativeTuple<'a> for OptionInstance {
impl<'a> ApplicativeSelect<'a> for OptionInstance {}
impl<'a> Applicative<'a> for OptionInstance {
fn discard_first<A: 'a, B: 'a>(fa: Self::F<A>, fb: Self::F<B>) -> Self::F<B> {
fn discard_first<A: 'a + Send, B: 'a + Send>(fa: Self::F<A>, fb: Self::F<B>) -> Self::F<B> {
fa?;
fb
}
fn discard_second<A: 'a, B: 'a>(fa: Self::F<A>, fb: Self::F<B>) -> Self::F<A> {
fn discard_second<A: 'a + Send, B: 'a + Send>(fa: Self::F<A>, fb: Self::F<B>) -> Self::F<A> {
fb?;
fa
}
}
impl<'a> Monad<'a> for OptionInstance {
fn bind<A: 'a, B: 'a>(fa: Self::F<A>, f: impl 'a + FnOnce(A) -> Self::F<B>) -> Self::F<B> {
fn bind<A: 'a + Send, B: 'a + Send>(
fa: Self::F<A>,
f: impl 'a + FnOnce(A) -> Self::F<B>,
) -> Self::F<B> {
f(fa?)
}
fn iterate<B: 'a>(mut f: impl Iterative<'a, T = Self, B = B>) -> Self::F<B> {
fn iterate<B: 'a + Send>(mut f: impl Iterative<'a, T = Self, B = B>) -> Self::F<B> {
loop {
match f.next()? {
ControlFlow::Continue(next_f) => f = next_f,
@ -92,13 +101,15 @@ impl<'a> Monad<'a> for OptionInstance {
}
}
fn join<A: 'a>(ffa: Self::F<Self::F<A>>) -> Self::F<A> {
fn join<A: 'a + Send>(ffa: Self::F<Self::F<A>>) -> Self::F<A> {
ffa?
}
}
impl<'a> LocalFunctor<'a> for OptionInstance {
fn unstuff<A: 'a, B: 'a>(state: Self::F<ControlFlow<B, A>>) -> ControlFlow<Self::F<B>, A> {
fn unstuff<A: 'a + Send, B: 'a + Send>(
state: Self::F<ControlFlow<B, A>>,
) -> ControlFlow<Self::F<B>, A> {
match state {
Some(ControlFlow::Continue(a)) => ControlFlow::Continue(a),
Some(ControlFlow::Break(b)) => ControlFlow::Break(Some(b)),
@ -106,7 +117,7 @@ impl<'a> LocalFunctor<'a> for OptionInstance {
}
}
fn stuff<A: 'a, T: Pure<'a>>(fa: Self::F<T::F<A>>) -> T::F<Self::F<A>> {
fn stuff<A: 'a + Send, T: Pure<'a>>(fa: Self::F<T::F<A>>) -> T::F<Self::F<A>> {
match fa {
Some(ua) => T::fmap(ua, Some),
None => T::pure(None),
@ -115,7 +126,7 @@ impl<'a> LocalFunctor<'a> for OptionInstance {
}
impl<'a> Fail<'a, ()> for OptionInstance {
fn fail<A: 'a>(_e: ()) -> Self::F<A> {
fn fail<A: 'a + Send>(_e: ()) -> Self::F<A> {
None
}
}
@ -127,7 +138,7 @@ mod option_tests {
use super::OptionInstance as T;
impl<'a> tests::Eqr<'a> for T {
fn eqr<A: PartialEq + std::fmt::Debug + 'a>(
fn eqr<A: 'a + Send + PartialEq + std::fmt::Debug>(
name: &'a str,
left: Self::F<A>,
right: Self::F<A>,
@ -137,7 +148,7 @@ mod option_tests {
}
impl<'a> test_suite::FunctorTestSuite<'a> for T {
fn sample<A: 'a, F: FnMut(&'a dyn Fn(A) -> Self::F<A>)>(mut f: F) {
fn sample<A: 'a + Send, F: FnMut(&'a (dyn Send + Sync + Fn(A) -> Self::F<A>))>(mut f: F) {
f(&|_| None);
f(&|a| Some(a));
}

View File

@ -12,34 +12,37 @@ use crate::func::class_prelude::*;
pub struct OverloadInstance<T, O>(T, O);
pub trait DeriveWeakFunctor {}
pub trait DeriveWeakFunctor: Send {}
impl<O: DeriveFunctor> DeriveWeakFunctor for O {}
pub trait DeriveFunctor {}
pub trait DeriveFunctor: Send {}
impl<O: DeriveApplicative> DeriveFunctor for O {}
pub trait DeriveApplicative {}
pub trait DeriveApplicative: Send {}
impl<O: DeriveMonad> DeriveApplicative for O {}
pub trait DeriveMonad {}
pub trait DeriveMonad: Send {}
impl<'a, T: WeakFunctor<'a>, O: 'a + DeriveWeakFunctor> WeakFunctor<'a> for OverloadInstance<T, O> {
type F<A: 'a> = T::F<A>;
type F<A: 'a + Send> = T::F<A>;
}
impl<'a, T: Functor<'a>, O: 'a + DeriveFunctor> Functor<'a> for OverloadInstance<T, O> {
fn fmap<A: 'a, B: 'a>(fa: Self::F<A>, f: impl 'a + FnOnce(A) -> B) -> Self::F<B> {
fn fmap<A: 'a + Send, B: 'a + Send>(
fa: Self::F<A>,
f: impl 'a + Send + FnOnce(A) -> B,
) -> Self::F<B> {
T::fmap(fa, f)
}
fn replace<A: 'a, B: 'a>(fa: Self::F<A>, b: B) -> Self::F<B> {
fn replace<A: 'a + Send, B: 'a + Send>(fa: Self::F<A>, b: B) -> Self::F<B> {
T::replace(fa, b)
}
fn void<A: 'a>(fa: Self::F<A>) -> Self::F<()> {
fn void<A: 'a + Send>(fa: Self::F<A>) -> Self::F<()> {
T::void(fa)
}
}
impl<'a, T: Pure<'a>, O: 'a + DeriveApplicative> Pure<'a> for OverloadInstance<T, O> {
fn pure<A: 'a>(a: A) -> Self::F<A> {
fn pure<A: 'a + Send>(a: A) -> Self::F<A> {
T::pure(a)
}
}
@ -47,7 +50,10 @@ impl<'a, T: Pure<'a>, O: 'a + DeriveApplicative> Pure<'a> for OverloadInstance<T
impl<'a, T: ApplicativeSeq<'a>, O: 'a + DeriveApplicative> ApplicativeSeq<'a>
for OverloadInstance<T, O>
{
fn seq<A: 'a, B: 'a>(ff: Self::F<impl 'a + FnOnce(A) -> B>, fa: Self::F<A>) -> Self::F<B> {
fn seq<A: 'a + Send, B: 'a + Send>(
ff: Self::F<impl 'a + Send + FnOnce(A) -> B>,
fa: Self::F<A>,
) -> Self::F<B> {
T::seq(ff, fa)
}
}
@ -55,10 +61,10 @@ impl<'a, T: ApplicativeSeq<'a>, O: 'a + DeriveApplicative> ApplicativeSeq<'a>
impl<'a, T: ApplicativeLA2<'a>, O: 'a + DeriveApplicative> ApplicativeLA2<'a>
for OverloadInstance<T, O>
{
fn la2<A: 'a, B: 'a, C: 'a>(
fn la2<A: 'a + Send, B: 'a + Send, C: 'a + Send>(
fa: Self::F<A>,
fb: Self::F<B>,
f: impl 'a + FnOnce(A, B) -> C,
f: impl 'a + Send + FnOnce(A, B) -> C,
) -> Self::F<C> {
T::la2(fa, fb, f)
}
@ -67,7 +73,7 @@ impl<'a, T: ApplicativeLA2<'a>, O: 'a + DeriveApplicative> ApplicativeLA2<'a>
impl<'a, T: ApplicativeTuple<'a>, O: 'a + DeriveApplicative> ApplicativeTuple<'a>
for OverloadInstance<T, O>
{
fn tuple<A: 'a, B: 'a>(fab: (Self::F<A>, Self::F<B>)) -> Self::F<(A, B)> {
fn tuple<A: 'a + Send, B: 'a + Send>(fab: (Self::F<A>, Self::F<B>)) -> Self::F<(A, B)> {
T::tuple(fab)
}
}
@ -75,7 +81,10 @@ impl<'a, T: ApplicativeTuple<'a>, O: 'a + DeriveApplicative> ApplicativeTuple<'a
impl<'a, T: ApplicativeSelect<'a>, O: 'a + DeriveApplicative> ApplicativeSelect<'a>
for OverloadInstance<T, O>
{
fn select<A: 'a, B: 'a>(fa: Self::F<A>, fb: Self::F<B>) -> SelectedWrapped<'a, A, B, Self> {
fn select<A: 'a + Send, B: 'a + Send>(
fa: Self::F<A>,
fb: Self::F<B>,
) -> SelectedWrapped<'a, A, B, Self> {
T::select_map(fa, fb, |selected| match selected {
Selected::A(a, fb) => Selected::A(a, fb),
Selected::B(fa, b) => Selected::B(fa, b),
@ -84,11 +93,11 @@ impl<'a, T: ApplicativeSelect<'a>, O: 'a + DeriveApplicative> ApplicativeSelect<
}
impl<'a, T: Applicative<'a>, O: 'a + DeriveApplicative> Applicative<'a> for OverloadInstance<T, O> {
fn discard_first<A: 'a, B: 'a>(fa: Self::F<A>, fb: Self::F<B>) -> Self::F<B> {
fn discard_first<A: 'a + Send, B: 'a + Send>(fa: Self::F<A>, fb: Self::F<B>) -> Self::F<B> {
T::discard_first(fa, fb)
}
fn discard_second<A: 'a, B: 'a>(fa: Self::F<A>, fb: Self::F<B>) -> Self::F<A> {
fn discard_second<A: 'a + Send, B: 'a + Send>(fa: Self::F<A>, fb: Self::F<B>) -> Self::F<A> {
T::discard_second(fa, fb)
}
}
@ -116,25 +125,30 @@ impl<'a, T: Monad<'a>, O: 'a + DeriveMonad, F: Iterative<'a, T = OverloadInstanc
}
impl<'a, T: Monad<'a>, O: 'a + DeriveMonad> Monad<'a> for OverloadInstance<T, O> {
fn bind<A: 'a, B: 'a>(fa: Self::F<A>, f: impl 'a + FnOnce(A) -> Self::F<B>) -> Self::F<B> {
fn bind<A: 'a + Send, B: 'a + Send>(
fa: Self::F<A>,
f: impl 'a + Send + FnOnce(A) -> Self::F<B>,
) -> Self::F<B> {
T::bind(fa, f)
}
fn iterate<B: 'a>(f: impl Iterative<'a, T = Self, B = B>) -> Self::F<B> {
fn iterate<B: 'a + Send>(f: impl Iterative<'a, T = Self, B = B>) -> Self::F<B> {
T::iterate(OverloadIterative::new(f))
}
fn join<A: 'a>(ffa: Self::F<Self::F<A>>) -> Self::F<A> {
fn join<A: 'a + Send>(ffa: Self::F<Self::F<A>>) -> Self::F<A> {
T::join(ffa)
}
}
pub struct DeriveFail<Ex>(Ex);
impl<Ex> DeriveMonad for DeriveFail<Ex> {}
impl<Ex: Send> DeriveMonad for DeriveFail<Ex> {}
impl<'a, E: 'a, Ex: 'a, T: MonadFail<'a, Result<E, Ex>>> Fail<'a, E> for EmbedFail<T, Ex> {
fn fail<A: 'a>(e: E) -> Self::F<A> {
impl<'a, E: 'a + Send, Ex: 'a + Send, T: MonadFail<'a, Result<E, Ex>>> Fail<'a, E>
for EmbedFail<T, Ex>
{
fn fail<A: 'a + Send>(e: E) -> Self::F<A> {
T::fail(Ok(e))
}
}
@ -142,19 +156,25 @@ impl<'a, E: 'a, Ex: 'a, T: MonadFail<'a, Result<E, Ex>>> Fail<'a, E> for EmbedFa
/// Instance of [`MonadFailAny`] for [`EmbedFail`].
pub struct DeriveFailAny<Ex, Fallible>(Ex, Fallible);
impl<'a, Ex: 'a, Fallible: MonadFailAny<'a>> MonadFailAny<'a> for DeriveFailAny<Ex, Fallible> {
type W<E: 'a> = EmbedFail<Fallible::W<Result<E, Ex>>, Ex>;
impl<'a, Ex: 'a + Send, Fallible: MonadFailAny<'a>> MonadFailAny<'a>
for DeriveFailAny<Ex, Fallible>
{
type W<E: 'a + Send> = EmbedFail<Fallible::W<Result<E, Ex>>, Ex>;
type T = Fallible::W<Ex>;
fn unstuff<A: 'a, E: 'a>(wa: WrapE<'a, A, E, Self>) -> Wrap<'a, Result<A, E>, Self::T> {
fn unstuff<A: 'a + Send, E: 'a + Send>(
wa: WrapE<'a, A, E, Self>,
) -> Wrap<'a, Result<A, E>, Self::T> {
Fallible::bind_err(<Self::W<E> as Functor>::fmap(wa, Ok), |err| match err {
Ok(e) => Fallible::pure(Err(e)),
Err(ex) => Fallible::fail(ex),
})
}
fn stuff<A: 'a, E: 'a>(fa: Wrap<'a, Result<A, E>, Self::T>) -> WrapE<'a, A, E, Self> {
fn stuff<A: 'a + Send, E: 'a + Send>(
fa: Wrap<'a, Result<A, E>, Self::T>,
) -> WrapE<'a, A, E, Self> {
Fallible::bind(fa, |result| match result {
Ok(Ok(a)) => Fallible::pure(a),
Ok(Err(e)) => Fallible::fail(Ok(e)),
@ -162,16 +182,16 @@ impl<'a, Ex: 'a, Fallible: MonadFailAny<'a>> MonadFailAny<'a> for DeriveFailAny<
})
}
fn map_err<A: 'a, E0: 'a, E1: 'a>(
fn map_err<A: 'a + Send, E0: 'a + Send, E1: 'a + Send>(
wa: WrapE<'a, A, E0, Self>,
f: impl 'a + FnOnce(E0) -> E1,
f: impl 'a + Send + FnOnce(E0) -> E1,
) -> WrapE<'a, A, E1, Self> {
Fallible::map_err(wa, |err| err.map(f))
}
fn bind_err<A: 'a, E0: 'a, E1: 'a>(
fn bind_err<A: 'a + Send, E0: 'a + Send, E1: 'a + Send>(
wa: WrapE<'a, A, E0, Self>,
f: impl 'a + FnOnce(E0) -> WrapE<'a, A, E1, Self>,
f: impl 'a + Send + FnOnce(E0) -> WrapE<'a, A, E1, Self>,
) -> WrapE<'a, A, E1, Self> {
Fallible::bind_err(wa, |err| match err {
Ok(e0) => f(e0),
@ -179,9 +199,9 @@ impl<'a, Ex: 'a, Fallible: MonadFailAny<'a>> MonadFailAny<'a> for DeriveFailAny<
})
}
fn bind<A: 'a, B: 'a, E0: 'a, E1: 'a>(
fn bind<A: 'a + Send, B: 'a + Send, E0: 'a + Send, E1: 'a + Send>(
wa: WrapE<'a, A, E0, Self>,
f: impl 'a + FnOnce(Result<A, E0>) -> WrapE<'a, B, E1, Self>,
f: impl 'a + Send + FnOnce(Result<A, E0>) -> WrapE<'a, B, E1, Self>,
) -> WrapE<'a, B, E1, Self> {
Fallible::bind(wa, |result| match result {
Ok(a) => f(Ok(a)),
@ -194,13 +214,13 @@ impl<'a, Ex: 'a, Fallible: MonadFailAny<'a>> MonadFailAny<'a> for DeriveFailAny<
impl<'a, T: SharedFunctor<'a>, O: 'a + DeriveWeakFunctor> SharedFunctor<'a>
for OverloadInstance<T, O>
{
type Shared<A: 'a + Clone> = T::Shared<A>;
type Shared<A: 'a + Send + Sync + Clone> = T::Shared<A>;
fn share<A: 'a + Clone>(fa: Self::F<A>) -> Self::Shared<A> {
fn share<A: 'a + Send + Sync + Clone>(fa: Self::F<A>) -> Self::Shared<A> {
T::share(fa)
}
fn unshare<A: 'a + Clone>(sa: Self::Shared<A>) -> Self::F<A> {
fn unshare<A: 'a + Send + Sync + Clone>(sa: Self::Shared<A>) -> Self::F<A> {
T::unshare(sa)
}
}

View File

@ -14,77 +14,105 @@
use crate::func::class_prelude::*;
#[derive(SharedFunctorAny)]
pub struct ResultInstance<E>(E);
pub struct ResultInstance<E: Send>(E);
impl<E> WeakFunctorAny for ResultInstance<E> {
type FAny<'a, A: 'a> = Result<A, E> where Self: 'a;
impl<E: Send + Sync + Clone> SharedFunctorAny for ResultInstance<E> {
type SharedAny<'a, A: 'a + Send + Sync + Clone> = Self::FAny<'a, A>
where
Self: 'a;
fn share<'a, A: 'a + Send + Sync + Clone>(fa: Self::FAny<'a, A>) -> Self::SharedAny<'a, A>
where
Self: 'a,
{
fa
}
impl<'a, E: 'a> Functor<'a> for ResultInstance<E> {
fn fmap<A: 'a, B: 'a>(fa: Self::F<A>, f: impl 'a + FnOnce(A) -> B) -> Self::F<B> {
fn unshare<'a, A: 'a + Send + Sync + Clone>(sa: Self::SharedAny<'a, A>) -> Self::FAny<'a, A>
where
Self: 'a,
{
sa
}
}
impl<E: Send> WeakFunctorAny for ResultInstance<E> {
type FAny<'a, A: 'a + Send> = Result<A, E> where Self: 'a;
}
impl<'a, E: 'a + Send> Functor<'a> for ResultInstance<E> {
fn fmap<A: 'a + Send, B: 'a + Send>(
fa: Self::F<A>,
f: impl 'a + Send + FnOnce(A) -> B,
) -> Self::F<B> {
fa.map(f)
}
fn replace<A: 'a, B: 'a>(fa: Self::F<A>, b: B) -> Self::F<B> {
fn replace<A: 'a + Send, B: 'a + Send>(fa: Self::F<A>, b: B) -> Self::F<B> {
fa?;
Self::pure(b)
}
fn void<A: 'a>(fa: Self::F<A>) -> Self::F<()> {
fn void<A: 'a + Send>(fa: Self::F<A>) -> Self::F<()> {
fa?;
Self::pure(())
}
}
impl<'a, E: 'a> Pure<'a> for ResultInstance<E> {
fn pure<A: 'a>(a: A) -> Self::F<A> {
impl<'a, E: 'a + Send> Pure<'a> for ResultInstance<E> {
fn pure<A: 'a + Send>(a: A) -> Self::F<A> {
Ok(a)
}
}
impl<'a, E: 'a> ApplicativeSeq<'a> for ResultInstance<E> {
fn seq<A: 'a, B: 'a>(ff: Self::F<impl 'a + FnOnce(A) -> B>, fa: Self::F<A>) -> Self::F<B> {
impl<'a, E: 'a + Send> ApplicativeSeq<'a> for ResultInstance<E> {
fn seq<A: 'a + Send, B: 'a + Send>(
ff: Self::F<impl 'a + Send + FnOnce(A) -> B>,
fa: Self::F<A>,
) -> Self::F<B> {
Self::pure(ff?(fa?))
}
}
impl<'a, E: 'a> ApplicativeLA2<'a> for ResultInstance<E> {
fn la2<A: 'a, B: 'a, C: 'a>(
impl<'a, E: 'a + Send> ApplicativeLA2<'a> for ResultInstance<E> {
fn la2<A: 'a + Send, B: 'a + Send, C: 'a + Send>(
fa: Self::F<A>,
fb: Self::F<B>,
f: impl 'a + FnOnce(A, B) -> C,
f: impl 'a + Send + FnOnce(A, B) -> C,
) -> Self::F<C> {
Self::pure(f(fa?, fb?))
}
}
impl<'a, E: 'a> ApplicativeTuple<'a> for ResultInstance<E> {
fn tuple<A: 'a, B: 'a>((fa, fb): (Self::F<A>, Self::F<B>)) -> Self::F<(A, B)> {
impl<'a, E: 'a + Send> ApplicativeTuple<'a> for ResultInstance<E> {
fn tuple<A: 'a + Send, B: 'a + Send>((fa, fb): (Self::F<A>, Self::F<B>)) -> Self::F<(A, B)> {
Self::pure((fa?, fb?))
}
}
impl<'a, E: 'a> ApplicativeSelect<'a> for ResultInstance<E> {}
impl<'a, E: 'a + Send> ApplicativeSelect<'a> for ResultInstance<E> {}
impl<'a, E: 'a> Applicative<'a> for ResultInstance<E> {
fn discard_first<A: 'a, B: 'a>(fa: Self::F<A>, fb: Self::F<B>) -> Self::F<B> {
impl<'a, E: 'a + Send> Applicative<'a> for ResultInstance<E> {
fn discard_first<A: 'a + Send, B: 'a + Send>(fa: Self::F<A>, fb: Self::F<B>) -> Self::F<B> {
fa?;
fb
}
fn discard_second<A: 'a, B: 'a>(fa: Self::F<A>, fb: Self::F<B>) -> Self::F<A> {
fn discard_second<A: 'a + Send, B: 'a + Send>(fa: Self::F<A>, fb: Self::F<B>) -> Self::F<A> {
fb?;
fa
}
}
impl<'a, E: 'a> Monad<'a> for ResultInstance<E> {
fn bind<A: 'a, B: 'a>(fa: Self::F<A>, f: impl 'a + FnOnce(A) -> Self::F<B>) -> Self::F<B> {
impl<'a, E: 'a + Send> Monad<'a> for ResultInstance<E> {
fn bind<A: 'a + Send, B: 'a + Send>(
fa: Self::F<A>,
f: impl 'a + FnOnce(A) -> Self::F<B>,
) -> Self::F<B> {
f(fa?)
}
fn iterate<B: 'a>(mut f: impl Iterative<'a, T = Self, B = B>) -> Self::F<B> {
fn iterate<B: 'a + Send>(mut f: impl Iterative<'a, T = Self, B = B>) -> Self::F<B> {
loop {
match f.next()? {
ControlFlow::Continue(next_f) => f = next_f,
@ -93,13 +121,15 @@ impl<'a, E: 'a> Monad<'a> for ResultInstance<E> {
}
}
fn join<A: 'a>(ffa: Self::F<Self::F<A>>) -> Self::F<A> {
fn join<A: 'a + Send>(ffa: Self::F<Self::F<A>>) -> Self::F<A> {
ffa?
}
}
impl<'a, E: 'a> LocalFunctor<'a> for ResultInstance<E> {
fn unstuff<A: 'a, B: 'a>(state: Self::F<ControlFlow<B, A>>) -> ControlFlow<Self::F<B>, A> {
impl<'a, E: 'a + Send> LocalFunctor<'a> for ResultInstance<E> {
fn unstuff<A: 'a + Send, B: 'a + Send>(
state: Self::F<ControlFlow<B, A>>,
) -> ControlFlow<Self::F<B>, A> {
match state {
Ok(ControlFlow::Continue(a)) => ControlFlow::Continue(a),
Ok(ControlFlow::Break(b)) => ControlFlow::Break(Ok(b)),
@ -107,7 +137,7 @@ impl<'a, E: 'a> LocalFunctor<'a> for ResultInstance<E> {
}
}
fn stuff<A: 'a, T: Pure<'a>>(fa: Self::F<T::F<A>>) -> T::F<Self::F<A>> {
fn stuff<A: 'a + Send, T: Pure<'a>>(fa: Self::F<T::F<A>>) -> T::F<Self::F<A>> {
match fa {
Ok(ua) => T::fmap(ua, Ok),
Err(e) => T::pure(Err(e)),
@ -115,20 +145,20 @@ impl<'a, E: 'a> LocalFunctor<'a> for ResultInstance<E> {
}
}
impl<'a, E: 'a> Fail<'a, E> for ResultInstance<E> {
fn fail<A: 'a>(e: E) -> Self::F<A> {
impl<'a, E: 'a + Send> Fail<'a, E> for ResultInstance<E> {
fn fail<A: 'a + Send>(e: E) -> Self::F<A> {
Err(e)
}
}
pub struct ResultFailAny;
trait ResultExt<'a, A: 'a, E0: 'a>: 'a {
fn bind_err<E1: 'a>(self, f: impl 'a + FnOnce(E0) -> Result<A, E1>) -> Result<A, E1>;
trait ResultExt<'a, A: 'a + Send, E0: 'a + Send>: 'a {
fn bind_err<E1: 'a + Send>(self, f: impl 'a + FnOnce(E0) -> Result<A, E1>) -> Result<A, E1>;
}
impl<'a, A: 'a, E0: 'a> ResultExt<'a, A, E0> for Result<A, E0> {
fn bind_err<E1: 'a>(self, f: impl 'a + FnOnce(E0) -> Result<A, E1>) -> Result<A, E1> {
impl<'a, A: 'a + Send, E0: 'a + Send> ResultExt<'a, A, E0> for Result<A, E0> {
fn bind_err<E1: 'a + Send>(self, f: impl 'a + FnOnce(E0) -> Result<A, E1>) -> Result<A, E1> {
match self {
Ok(a) => Ok(a),
Err(e) => f(e),
@ -137,40 +167,44 @@ impl<'a, A: 'a, E0: 'a> ResultExt<'a, A, E0> for Result<A, E0> {
}
impl<'a> MonadFailAny<'a> for ResultFailAny {
type W<E: 'a> = ResultInstance<E>;
type W<E: 'a + Send> = ResultInstance<E>;
type T = instances::solo::SoloInstance;
fn unstuff<A: 'a, E: 'a>(wa: WrapE<'a, A, E, Self>) -> Wrap<'a, Result<A, E>, Self::T> {
fn unstuff<A: 'a + Send, E: 'a + Send>(
wa: WrapE<'a, A, E, Self>,
) -> Wrap<'a, Result<A, E>, Self::T> {
wa
}
fn stuff<A: 'a, E: 'a>(fa: Wrap<'a, Result<A, E>, Self::T>) -> WrapE<'a, A, E, Self> {
fn stuff<A: 'a + Send, E: 'a + Send>(
fa: Wrap<'a, Result<A, E>, Self::T>,
) -> WrapE<'a, A, E, Self> {
fa
}
fn map_err<A: 'a, E0: 'a, E1: 'a>(
fn map_err<A: 'a + Send, E0: 'a + Send, E1: 'a + Send>(
wa: WrapE<'a, A, E0, Self>,
f: impl 'a + FnOnce(E0) -> E1,
) -> WrapE<'a, A, E1, Self> {
wa.map_err(f)
}
fn bind_err<A: 'a, E0: 'a, E1: 'a>(
fn bind_err<A: 'a + Send, E0: 'a + Send, E1: 'a + Send>(
wa: WrapE<'a, A, E0, Self>,
f: impl 'a + FnOnce(E0) -> WrapE<'a, A, E1, Self>,
) -> WrapE<'a, A, E1, Self> {
wa.bind_err(f)
}
fn bind<A: 'a, B: 'a, E0: 'a, E1: 'a>(
fn bind<A: 'a + Send, B: 'a + Send, E0: 'a + Send, E1: 'a + Send>(
wa: WrapE<'a, A, E0, Self>,
f: impl 'a + FnOnce(Result<A, E0>) -> WrapE<'a, B, E1, Self>,
) -> WrapE<'a, B, E1, Self> {
f(wa)
}
fn rotate_out<A: 'a, E0: 'a, E1: 'a>(
fn rotate_out<A: 'a + Send, E0: 'a + Send, E1: 'a + Send>(
wa: WrapE<'a, Result<A, E1>, E0, Self>,
) -> WrapE<'a, A, Result<E1, E0>, Self> {
match wa {
@ -184,28 +218,32 @@ impl<'a> MonadFailAny<'a> for ResultFailAny {
pub struct ResultFailOver<T>(T);
impl<'a, T: Monad<'a>> MonadFailAny<'a> for ResultFailOver<T> {
type W<E: 'a> = super::composition::CompositionInstance<T, ResultInstance<E>>;
type W<E: 'a + Send> = super::composition::CompositionInstance<T, ResultInstance<E>>;
type T = T;
fn unstuff<A: 'a, E: 'a>(wa: WrapE<'a, A, E, Self>) -> Wrap<'a, Result<A, E>, Self::T> {
fn unstuff<A: 'a + Send, E: 'a + Send>(
wa: WrapE<'a, A, E, Self>,
) -> Wrap<'a, Result<A, E>, Self::T> {
wa
}
fn stuff<A: 'a, E: 'a>(fa: Wrap<'a, Result<A, E>, Self::T>) -> WrapE<'a, A, E, Self> {
fn stuff<A: 'a + Send, E: 'a + Send>(
fa: Wrap<'a, Result<A, E>, Self::T>,
) -> WrapE<'a, A, E, Self> {
fa
}
fn map_err<A: 'a, E0: 'a, E1: 'a>(
fn map_err<A: 'a + Send, E0: 'a + Send, E1: 'a + Send>(
wa: WrapE<'a, A, E0, Self>,
f: impl 'a + FnOnce(E0) -> E1,
f: impl 'a + Send + FnOnce(E0) -> E1,
) -> WrapE<'a, A, E1, Self> {
T::fmap(wa, |a| a.map_err(f))
}
fn bind_err<A: 'a, E0: 'a, E1: 'a>(
fn bind_err<A: 'a + Send, E0: 'a + Send, E1: 'a + Send>(
wa: WrapE<'a, A, E0, Self>,
f: impl 'a + FnOnce(E0) -> WrapE<'a, A, E1, Self>,
f: impl 'a + Send + FnOnce(E0) -> WrapE<'a, A, E1, Self>,
) -> WrapE<'a, A, E1, Self> {
T::bind(wa, |a| match a {
Ok(a) => T::pure(Ok(a)),
@ -213,14 +251,14 @@ impl<'a, T: Monad<'a>> MonadFailAny<'a> for ResultFailOver<T> {
})
}
fn bind<A: 'a, B: 'a, E0: 'a, E1: 'a>(
fn bind<A: 'a + Send, B: 'a + Send, E0: 'a + Send, E1: 'a + Send>(
wa: WrapE<'a, A, E0, Self>,
f: impl 'a + FnOnce(Result<A, E0>) -> WrapE<'a, B, E1, Self>,
f: impl 'a + Send + FnOnce(Result<A, E0>) -> WrapE<'a, B, E1, Self>,
) -> WrapE<'a, B, E1, Self> {
T::bind(wa, f)
}
fn rotate_out<A: 'a, E0: 'a, E1: 'a>(
fn rotate_out<A: 'a + Send, E0: 'a + Send, E1: 'a + Send>(
wa: WrapE<'a, Result<A, E1>, E0, Self>,
) -> WrapE<'a, A, Result<E1, E0>, Self> {
T::fmap(wa, <ResultFailAny as MonadFailAny>::rotate_out)

View File

@ -14,48 +14,51 @@ use crate::func::class_prelude::*;
pub struct SoloInstance;
impl WeakFunctorAny for SoloInstance {
type FAny<'a, A: 'a> = A;
type FAny<'a, A: 'a + Send> = A;
}
impl<'a> Functor<'a> for SoloInstance {
fn fmap<A: 'a, B: 'a>(fa: Self::F<A>, f: impl 'a + FnOnce(A) -> B) -> Self::F<B> {
fn fmap<A: 'a + Send, B: 'a + Send>(fa: Self::F<A>, f: impl 'a + FnOnce(A) -> B) -> Self::F<B> {
f(fa)
}
fn replace<A: 'a, B: 'a>(fa: Self::F<A>, b: B) -> Self::F<B> {
fn replace<A: 'a + Send, B: 'a + Send>(fa: Self::F<A>, b: B) -> Self::F<B> {
drop(fa);
b
}
fn void<A: 'a>(fa: Self::F<A>) -> Self::F<()> {
fn void<A: 'a + Send>(fa: Self::F<A>) -> Self::F<()> {
drop(fa);
}
}
impl<'a> Pure<'a> for SoloInstance {
fn pure<A: 'a>(a: A) -> Self::F<A> {
fn pure<A: 'a + Send>(a: A) -> Self::F<A> {
a
}
}
impl<'a> ApplicativeSeq<'a> for SoloInstance {
fn seq<A: 'a, B: 'a>(ff: Self::F<impl 'a + FnOnce(A) -> B>, fa: Self::F<A>) -> Self::F<B> {
fn seq<A: 'a + Send, B: 'a + Send>(
ff: Self::F<impl 'a + Send + FnOnce(A) -> B>,
fa: Self::F<A>,
) -> Self::F<B> {
ff(fa)
}
}
impl<'a> ApplicativeLA2<'a> for SoloInstance {
fn la2<A: 'a, B: 'a, C: 'a>(
fn la2<A: 'a + Send, B: 'a + Send, C: 'a + Send>(
fa: Self::F<A>,
fb: Self::F<B>,
f: impl 'a + FnOnce(A, B) -> C,
f: impl 'a + Send + FnOnce(A, B) -> C,
) -> Self::F<C> {
f(fa, fb)
}
}
impl<'a> ApplicativeTuple<'a> for SoloInstance {
fn tuple<A: 'a, B: 'a>((fa, fb): (Self::F<A>, Self::F<B>)) -> Self::F<(A, B)> {
fn tuple<A: 'a + Send, B: 'a + Send>((fa, fb): (Self::F<A>, Self::F<B>)) -> Self::F<(A, B)> {
(fa, fb)
}
}
@ -63,23 +66,26 @@ impl<'a> ApplicativeTuple<'a> for SoloInstance {
impl<'a> ApplicativeSelect<'a> for SoloInstance {}
impl<'a> Applicative<'a> for SoloInstance {
fn discard_first<A: 'a, B: 'a>(fa: Self::F<A>, fb: Self::F<B>) -> Self::F<B> {
fn discard_first<A: 'a + Send, B: 'a + Send>(fa: Self::F<A>, fb: Self::F<B>) -> Self::F<B> {
drop(fa);
fb
}
fn discard_second<A: 'a, B: 'a>(fa: Self::F<A>, fb: Self::F<B>) -> Self::F<A> {
fn discard_second<A: 'a + Send, B: 'a + Send>(fa: Self::F<A>, fb: Self::F<B>) -> Self::F<A> {
drop(fb);
fa
}
}
impl<'a> Monad<'a> for SoloInstance {
fn bind<A: 'a, B: 'a>(fa: Self::F<A>, f: impl 'a + FnOnce(A) -> Self::F<B>) -> Self::F<B> {
fn bind<A: 'a + Send, B: 'a + Send>(
fa: Self::F<A>,
f: impl 'a + FnOnce(A) -> Self::F<B>,
) -> Self::F<B> {
f(fa)
}
fn iterate<B: 'a>(mut f: impl Iterative<'a, T = Self, B = B>) -> Self::F<B> {
fn iterate<B: 'a + Send>(mut f: impl Iterative<'a, T = Self, B = B>) -> Self::F<B> {
loop {
match f.next() {
ControlFlow::Continue(next_f) => f = next_f,
@ -88,23 +94,25 @@ impl<'a> Monad<'a> for SoloInstance {
}
}
fn join<A: 'a>(ffa: Self::F<Self::F<A>>) -> Self::F<A> {
fn join<A: 'a + Send>(ffa: Self::F<Self::F<A>>) -> Self::F<A> {
ffa
}
}
impl<'a> LocalFunctor<'a> for SoloInstance {
fn unstuff<A: 'a, B: 'a>(state: Self::F<ControlFlow<B, A>>) -> ControlFlow<Self::F<B>, A> {
fn unstuff<A: 'a + Send, B: 'a + Send>(
state: Self::F<ControlFlow<B, A>>,
) -> ControlFlow<Self::F<B>, A> {
state
}
fn stuff<A: 'a, T: Pure<'a>>(fa: Self::F<T::F<A>>) -> T::F<Self::F<A>> {
fn stuff<A: 'a + Send, T: Pure<'a>>(fa: Self::F<T::F<A>>) -> T::F<Self::F<A>> {
fa
}
}
impl<'a> Fail<'a, std::convert::Infallible> for SoloInstance {
fn fail<A: 'a>(e: std::convert::Infallible) -> Self::F<A> {
fn fail<A: 'a + Send>(e: std::convert::Infallible) -> Self::F<A> {
match e {}
}
}

View File

@ -6,7 +6,7 @@
//! [`lazy`]: super::lazy
use std::marker::PhantomData;
use std::{cell::Cell, rc::Rc};
use std::{cell::Cell, sync::Arc};
use crate::func::class_prelude::*;
use crate::func::derivations::{ApplicativeLA2ViaSeq, ApplicativeTupleViaLA2};
@ -83,14 +83,14 @@ impl<'a> EvalTree<'a> {
}
}
trait IntoOet<A> {
trait IntoOet<A>: Send {
fn into_oet<'t>(self: Box<Self>, f: Box<dyn 't + FnOnce(A)>) -> Oet<'t>
where
Self: 't,
A: 't;
}
impl<'a, A: 'a, B: 'a, F: 'a + FnOnce(A) -> Stackless<'a, B>> IntoOet<B>
impl<'a, A: 'a + Send, B: 'a + Send, F: 'a + Send + FnOnce(A) -> Stackless<'a, B>> IntoOet<B>
for Wrapper<(&'a (), B), (Stackless<'a, A>, F)>
{
fn into_oet<'t>(self: Box<Self>, f: Box<dyn 't + FnOnce(B)>) -> Oet<'t>
@ -98,7 +98,7 @@ impl<'a, A: 'a, B: 'a, F: 'a + FnOnce(A) -> Stackless<'a, B>> IntoOet<B>
Self: 't,
A: 't,
{
let cell_l = Rc::new(Cell::new(None));
let cell_l = Arc::new(Cell::new(None));
let cell_r = cell_l.clone();
let (sstackless, sf) = self.0;
Some(EvalTree::Composite(
@ -111,7 +111,7 @@ impl<'a, A: 'a, B: 'a, F: 'a + FnOnce(A) -> Stackless<'a, B>> IntoOet<B>
}
}
impl<'a, A: 'a, B: 'a, F: 'a + FnOnce(A) -> B> IntoOet<B>
impl<'a, A: 'a + Send, B: 'a + Send, F: 'a + Send + FnOnce(A) -> B> IntoOet<B>
for Wrapper<(&'a (), B, ()), (Stackless<'a, A>, F)>
{
fn into_oet<'t>(self: Box<Self>, f: Box<dyn 't + FnOnce(B)>) -> Oet<'t>
@ -119,7 +119,7 @@ impl<'a, A: 'a, B: 'a, F: 'a + FnOnce(A) -> B> IntoOet<B>
Self: 't,
A: 't,
{
let cell_l = Rc::new(Cell::new(None));
let cell_l = Arc::new(Cell::new(None));
let cell_r = cell_l.clone();
let (sstackless, sf) = self.0;
Some(EvalTree::Composite(
@ -135,7 +135,7 @@ impl<'a, A: 'a, B: 'a, F: 'a + FnOnce(A) -> B> IntoOet<B>
}
}
impl<A> IntoOet<A> for Wrapper<(), A> {
impl<A: Send> IntoOet<A> for Wrapper<(), A> {
fn into_oet<'t>(self: Box<Self>, f: Box<dyn 't + FnOnce(A)>) -> Oet<'t>
where
Self: 't,
@ -152,39 +152,42 @@ type StackessDyn<'a, A> = dyn 'a + IntoOet<A>;
pub struct Stackless<'a, A: 'a>(Box<StackessDyn<'a, A>>);
fn set_cell<A>(cell: Rc<Cell<Option<A>>>, a: A) {
fn set_cell<A>(cell: Arc<Cell<Option<A>>>, a: A) {
if cell.replace(Some(a)).is_some() {
panic!("MITM overwritten")
}
}
fn get_cell<A>(cell: Rc<Cell<Option<A>>>) -> A {
fn get_cell<A>(cell: Arc<Cell<Option<A>>>) -> A {
match cell.replace(None) {
Some(val) => val,
None => panic!("MITM not set"),
}
}
impl<'a, A: 'a> Stackless<'a, A> {
impl<'a, A: 'a + Send> Stackless<'a, A> {
fn call(self, f: impl 'a + FnOnce(A)) -> Oet<'a> {
self.0.into_oet(Box::new(f))
}
/// Method-like equivalent of [`Monad::bind`],
/// the preferred way to chain [`Stackless<A>`] and `FnOnce(A) -> Stackless<B>` into [`Stackless<B>`].
pub fn bind<B: 'a>(self, f: impl 'a + FnOnce(A) -> Stackless<'a, B>) -> Stackless<'a, B> {
pub fn bind<B: 'a + Send>(
self,
f: impl 'a + Send + FnOnce(A) -> Stackless<'a, B>,
) -> Stackless<'a, B> {
Stackless(Box::new(Wrapper((self, f), PhantomData)))
}
/// Method-like equivalent of [`Functor::fmap`].
pub fn map<B: 'a>(self, f: impl 'a + FnOnce(A) -> B) -> Stackless<'a, B> {
pub fn map<B: 'a + Send>(self, f: impl 'a + Send + FnOnce(A) -> B) -> Stackless<'a, B> {
Stackless(Box::new(Wrapper((self, f), PhantomData)))
}
/// Evaluate. Process is loop-like on the inside
/// with the least amount of recursion the current model allows to use.
pub fn evaluate(self) -> A {
let ocell = Rc::new(Cell::new(None));
let ocell = Arc::new(Cell::new(None));
let icell = ocell.clone();
let mut eval = self.call(|a| set_cell(icell, a));
while let Some(tree) = eval {
@ -194,7 +197,7 @@ impl<'a, A: 'a> Stackless<'a, A> {
}
}
impl<'a, A: 'a> From<A> for Stackless<'a, A> {
impl<'a, A: 'a + Send> From<A> for Stackless<'a, A> {
fn from(value: A) -> Self {
Stackless(Box::new(Wrapper(value, PhantomData)))
}
@ -203,39 +206,45 @@ impl<'a, A: 'a> From<A> for Stackless<'a, A> {
pub struct StacklessInstance;
impl WeakFunctorAny for StacklessInstance {
type FAny<'a, A: 'a> = Stackless<'a, A>;
type FAny<'a, A: 'a + Send> = Stackless<'a, A>;
}
impl<'a> Functor<'a> for StacklessInstance {
fn fmap<A: 'a, B: 'a>(fa: Self::F<A>, f: impl 'a + FnOnce(A) -> B) -> Self::F<B> {
fn fmap<A: 'a + Send, B: 'a + Send>(
fa: Self::F<A>,
f: impl 'a + Send + FnOnce(A) -> B,
) -> Self::F<B> {
fa.map(f)
}
}
impl<'a> Pure<'a> for StacklessInstance {
fn pure<A: 'a>(a: A) -> Self::F<A> {
fn pure<A: 'a + Send>(a: A) -> Self::F<A> {
Stackless::from(a)
}
}
impl<'a> ApplicativeSeq<'a> for StacklessInstance {
fn seq<A: 'a, B: 'a>(ff: Self::F<impl 'a + FnOnce(A) -> B>, fa: Self::F<A>) -> Self::F<B> {
fn seq<A: 'a + Send, B: 'a + Send>(
ff: Self::F<impl 'a + Send + FnOnce(A) -> B>,
fa: Self::F<A>,
) -> Self::F<B> {
ff.bind(|f| fa.map(f))
}
}
impl<'a> ApplicativeLA2<'a> for StacklessInstance {
fn la2<A: 'a, B: 'a, C: 'a>(
fn la2<A: 'a + Send, B: 'a + Send, C: 'a + Send>(
fa: Self::F<A>,
fb: Self::F<B>,
f: impl 'a + FnOnce(A, B) -> C,
f: impl 'a + Send + FnOnce(A, B) -> C,
) -> Self::F<C> {
Self::_la2_via_seq(f, fa, fb)
}
}
impl<'a> ApplicativeTuple<'a> for StacklessInstance {
fn tuple<A: 'a, B: 'a>((fa, fb): (Self::F<A>, Self::F<B>)) -> Self::F<(A, B)> {
fn tuple<A: 'a + Send, B: 'a + Send>((fa, fb): (Self::F<A>, Self::F<B>)) -> Self::F<(A, B)> {
Self::_tuple_via_la2((fa, fb))
}
}
@ -245,11 +254,14 @@ impl<'a> ApplicativeSelect<'a> for StacklessInstance {}
impl<'a> Applicative<'a> for StacklessInstance {}
impl<'a> Monad<'a> for StacklessInstance {
fn bind<A: 'a, B: 'a>(fa: Self::F<A>, f: impl 'a + FnOnce(A) -> Self::F<B>) -> Self::F<B> {
fn bind<A: 'a + Send, B: 'a + Send>(
fa: Self::F<A>,
f: impl 'a + Send + FnOnce(A) -> Self::F<B>,
) -> Self::F<B> {
fa.bind(f)
}
fn iterate<B: 'a>(f: impl Iterative<'a, T = Self, B = B>) -> Self::F<B> {
fn iterate<B: 'a + Send>(f: impl Iterative<'a, T = Self, B = B>) -> Self::F<B> {
Self::pure(()).bind(move |_| {
f.next().bind(|state| match state {
ControlFlow::Continue(next_f) => Self::iterate(next_f),
@ -266,7 +278,7 @@ mod stackless_test {
use super::StacklessInstance as T;
impl<'a> tests::Eqr<'a> for T {
fn eqr<A: PartialEq + std::fmt::Debug + 'a>(
fn eqr<A: 'a + Send + PartialEq + std::fmt::Debug>(
name: &'a str,
left: Self::F<A>,
right: Self::F<A>,
@ -276,7 +288,7 @@ mod stackless_test {
}
impl<'a> test_suite::FunctorTestSuite<'a> for T {
fn sample<A: 'a, F: FnMut(&'a dyn Fn(A) -> Self::F<A>)>(mut f: F) {
fn sample<A: 'a + Send, F: FnMut(&'a (dyn Send + Sync + Fn(A) -> Self::F<A>))>(mut f: F) {
f(&|a| a.into());
}
}

View File

@ -19,16 +19,19 @@ use crate::func::class_prelude::*;
pub struct TryFutureInstance<E>(E);
impl<E> WeakFunctorAny for TryFutureInstance<E> {
type FAny<'a, A: 'a> = Pin<Box<dyn 'a + Future<Output = Result<A, E>>>> where Self: 'a;
impl<E: Send> WeakFunctorAny for TryFutureInstance<E> {
type FAny<'a, A: 'a + Send> = Pin<Box<dyn 'a + Send + Future<Output = Result<A, E>>>> where Self: 'a;
}
impl<'a, E: 'a> Functor<'a> for TryFutureInstance<E> {
fn fmap<A: 'a, B: 'a>(fa: Self::F<A>, f: impl 'a + FnOnce(A) -> B) -> Self::F<B> {
impl<'a, E: 'a + Send> Functor<'a> for TryFutureInstance<E> {
fn fmap<A: 'a + Send, B: 'a + Send>(
fa: Self::F<A>,
f: impl 'a + Send + FnOnce(A) -> B,
) -> Self::F<B> {
Box::pin(async { Ok(f(fa.await?)) })
}
fn replace<A: 'a, B: 'a>(fa: Self::F<A>, b: B) -> Self::F<B> {
fn replace<A: 'a + Send, B: 'a + Send>(fa: Self::F<A>, b: B) -> Self::F<B> {
Box::pin(async {
fa.await?;
Ok(b)
@ -36,14 +39,17 @@ impl<'a, E: 'a> Functor<'a> for TryFutureInstance<E> {
}
}
impl<'a, E: 'a> Pure<'a> for TryFutureInstance<E> {
fn pure<A: 'a>(a: A) -> Self::F<A> {
impl<'a, E: 'a + Send> Pure<'a> for TryFutureInstance<E> {
fn pure<A: 'a + Send>(a: A) -> Self::F<A> {
Box::pin(async { Ok(a) })
}
}
impl<'a, E: 'a> ApplicativeSeq<'a> for TryFutureInstance<E> {
fn seq<A: 'a, B: 'a>(ff: Self::F<impl 'a + FnOnce(A) -> B>, fa: Self::F<A>) -> Self::F<B> {
impl<'a, E: 'a + Send> ApplicativeSeq<'a> for TryFutureInstance<E> {
fn seq<A: 'a + Send, B: 'a + Send>(
ff: Self::F<impl 'a + Send + FnOnce(A) -> B>,
fa: Self::F<A>,
) -> Self::F<B> {
Box::pin(async {
let (f, a) = try_join!(ff, fa)?;
Ok(f(a))
@ -51,11 +57,11 @@ impl<'a, E: 'a> ApplicativeSeq<'a> for TryFutureInstance<E> {
}
}
impl<'a, E: 'a> ApplicativeLA2<'a> for TryFutureInstance<E> {
fn la2<A: 'a, B: 'a, C: 'a>(
impl<'a, E: 'a + Send> ApplicativeLA2<'a> for TryFutureInstance<E> {
fn la2<A: 'a + Send, B: 'a + Send, C: 'a + Send>(
fa: Self::F<A>,
fb: Self::F<B>,
f: impl 'a + FnOnce(A, B) -> C,
f: impl 'a + Send + FnOnce(A, B) -> C,
) -> Self::F<C> {
Box::pin(async {
let (a, b) = try_join!(fa, fb)?;
@ -64,14 +70,17 @@ impl<'a, E: 'a> ApplicativeLA2<'a> for TryFutureInstance<E> {
}
}
impl<'a, E: 'a> ApplicativeTuple<'a> for TryFutureInstance<E> {
fn tuple<A: 'a, B: 'a>((fa, fb): (Self::F<A>, Self::F<B>)) -> Self::F<(A, B)> {
impl<'a, E: 'a + Send> ApplicativeTuple<'a> for TryFutureInstance<E> {
fn tuple<A: 'a + Send, B: 'a + Send>((fa, fb): (Self::F<A>, Self::F<B>)) -> Self::F<(A, B)> {
Box::pin(async { try_join!(fa, fb) })
}
}
impl<'a, E: 'a> ApplicativeSelect<'a> for TryFutureInstance<E> {
fn select<A: 'a, B: 'a>(fa: Self::F<A>, fb: Self::F<B>) -> SelectedWrapped<'a, A, B, Self> {
impl<'a, E: 'a + Send> ApplicativeSelect<'a> for TryFutureInstance<E> {
fn select<A: 'a + Send, B: 'a + Send>(
fa: Self::F<A>,
fb: Self::F<B>,
) -> SelectedWrapped<'a, A, B, Self> {
Box::pin(async {
match try_select(fa, fb).await {
Ok(Either::Left((a, fb))) => Ok(Selected::A(a, fb)),
@ -83,22 +92,25 @@ impl<'a, E: 'a> ApplicativeSelect<'a> for TryFutureInstance<E> {
}
}
impl<'a, E: 'a> Applicative<'a> for TryFutureInstance<E> {
fn discard_first<A: 'a, B: 'a>(fa: Self::F<A>, fb: Self::F<B>) -> Self::F<B> {
impl<'a, E: 'a + Send> Applicative<'a> for TryFutureInstance<E> {
fn discard_first<A: 'a + Send, B: 'a + Send>(fa: Self::F<A>, fb: Self::F<B>) -> Self::F<B> {
Box::pin(async { Ok(try_join!(fa, fb)?.1) })
}
fn discard_second<A: 'a, B: 'a>(fa: Self::F<A>, fb: Self::F<B>) -> Self::F<A> {
fn discard_second<A: 'a + Send, B: 'a + Send>(fa: Self::F<A>, fb: Self::F<B>) -> Self::F<A> {
Box::pin(async { Ok(try_join!(fa, fb)?.0) })
}
}
impl<'a, E: 'a> Monad<'a> for TryFutureInstance<E> {
fn bind<A: 'a, B: 'a>(fa: Self::F<A>, f: impl 'a + FnOnce(A) -> Self::F<B>) -> Self::F<B> {
impl<'a, E: 'a + Send> Monad<'a> for TryFutureInstance<E> {
fn bind<A: 'a + Send, B: 'a + Send>(
fa: Self::F<A>,
f: impl 'a + Send + FnOnce(A) -> Self::F<B>,
) -> Self::F<B> {
Box::pin(async { f(fa.await?).await })
}
fn iterate<B: 'a>(mut f: impl Iterative<'a, T = Self, B = B>) -> Self::F<B> {
fn iterate<B: 'a + Send>(mut f: impl Iterative<'a, T = Self, B = B>) -> Self::F<B> {
Box::pin(async move {
loop {
match f.next().await? {
@ -109,25 +121,26 @@ impl<'a, E: 'a> Monad<'a> for TryFutureInstance<E> {
})
}
fn join<A: 'a>(ffa: Self::F<Self::F<A>>) -> Self::F<A> {
fn join<A: 'a + Send>(ffa: Self::F<Self::F<A>>) -> Self::F<A> {
Box::pin(async { ffa.await?.await })
}
}
impl<'a, E: 'a + Clone> SharedFunctor<'a> for TryFutureInstance<E> {
type Shared<A: 'a + Clone> = Shared<Pin<Box<dyn 'a + Future<Output = Result<A, E>>>>>;
impl<'a, E: 'a + Send + Sync + Clone> SharedFunctor<'a> for TryFutureInstance<E> {
type Shared<A: 'a + Send + Sync + Clone> =
Shared<Pin<Box<dyn 'a + Send + Future<Output = Result<A, E>>>>>;
fn share<A: 'a + Clone>(fa: Self::F<A>) -> Self::Shared<A> {
fn share<A: 'a + Send + Sync + Clone>(fa: Self::F<A>) -> Self::Shared<A> {
fa.shared()
}
fn unshare<A: 'a + Clone>(sa: Self::Shared<A>) -> Self::F<A> {
fn unshare<A: 'a + Send + Sync + Clone>(sa: Self::Shared<A>) -> Self::F<A> {
Box::pin(sa)
}
}
impl<'a, E: 'a> Fail<'a, E> for TryFutureInstance<E> {
fn fail<A: 'a>(e: E) -> Self::F<A> {
impl<'a, E: 'a + Send> Fail<'a, E> for TryFutureInstance<E> {
fn fail<A: 'a + Send>(e: E) -> Self::F<A> {
Box::pin(async { Err(e) })
}
}
@ -135,28 +148,32 @@ impl<'a, E: 'a> Fail<'a, E> for TryFutureInstance<E> {
pub struct FutureFailAny;
impl<'a> MonadFailAny<'a> for FutureFailAny {
type W<E: 'a> = TryFutureInstance<E>;
type W<E: 'a + Send> = TryFutureInstance<E>;
type T = instances::future::FutureInstance;
fn unstuff<A: 'a, E: 'a>(wa: WrapE<'a, A, E, Self>) -> Wrap<'a, Result<A, E>, Self::T> {
fn unstuff<A: 'a + Send, E: 'a + Send>(
wa: WrapE<'a, A, E, Self>,
) -> Wrap<'a, Result<A, E>, Self::T> {
wa
}
fn stuff<A: 'a, E: 'a>(fa: Wrap<'a, Result<A, E>, Self::T>) -> WrapE<'a, A, E, Self> {
fn stuff<A: 'a + Send, E: 'a + Send>(
fa: Wrap<'a, Result<A, E>, Self::T>,
) -> WrapE<'a, A, E, Self> {
fa
}
fn map_err<A: 'a, E0: 'a, E1: 'a>(
fn map_err<A: 'a + Send, E0: 'a + Send, E1: 'a + Send>(
wa: WrapE<'a, A, E0, Self>,
f: impl 'a + FnOnce(E0) -> E1,
f: impl 'a + Send + FnOnce(E0) -> E1,
) -> WrapE<'a, A, E1, Self> {
Box::pin(async { wa.await.map_err(f) })
}
fn bind_err<A: 'a, E0: 'a, E1: 'a>(
fn bind_err<A: 'a + Send, E0: 'a + Send, E1: 'a + Send>(
wa: WrapE<'a, A, E0, Self>,
f: impl 'a + FnOnce(E0) -> WrapE<'a, A, E1, Self>,
f: impl 'a + Send + FnOnce(E0) -> WrapE<'a, A, E1, Self>,
) -> WrapE<'a, A, E1, Self> {
Box::pin(async {
match wa.await {
@ -166,14 +183,14 @@ impl<'a> MonadFailAny<'a> for FutureFailAny {
})
}
fn bind<A: 'a, B: 'a, E0: 'a, E1: 'a>(
fn bind<A: 'a + Send, B: 'a + Send, E0: 'a + Send, E1: 'a + Send>(
wa: WrapE<'a, A, E0, Self>,
f: impl 'a + FnOnce(Result<A, E0>) -> WrapE<'a, B, E1, Self>,
f: impl 'a + Send + FnOnce(Result<A, E0>) -> WrapE<'a, B, E1, Self>,
) -> WrapE<'a, B, E1, Self> {
Box::pin(async { f(wa.await).await })
}
fn rotate_out<A: 'a, E0: 'a, E1: 'a>(
fn rotate_out<A: 'a + Send, E0: 'a + Send, E1: 'a + Send>(
wa: WrapE<'a, Result<A, E1>, E0, Self>,
) -> WrapE<'a, A, Result<E1, E0>, Self> {
Box::pin(async {

View File

@ -3,10 +3,12 @@ use super::{controlflow::ControlFlowInstance, *};
/// Represents wrapped results which are instantly available.
pub trait LocalFunctor<'a>: WeakFunctor<'a> {
/// Extract iteration state, if successful.
fn unstuff<A: 'a, B: 'a>(state: Self::F<ControlFlow<B, A>>) -> ControlFlow<Self::F<B>, A> {
fn unstuff<A: 'a + Send, B: 'a + Send>(
state: Self::F<ControlFlow<B, A>>,
) -> ControlFlow<Self::F<B>, A> {
Self::stuff::<_, ControlFlowInstance<_>>(state)
}
/// Stuff wrapped result into another functor.
fn stuff<A: 'a, T: Pure<'a>>(fa: Self::F<T::F<A>>) -> T::F<Self::F<A>>;
fn stuff<A: 'a + Send, T: Pure<'a>>(fa: Self::F<T::F<A>>) -> T::F<Self::F<A>>;
}

View File

@ -2,35 +2,35 @@ use super::{weakfunctorany::WeakFunctorAny, WeakFunctor};
pub use radn_derive::SharedFunctorAny;
pub trait SharedFunctorAny: WeakFunctorAny {
type SharedAny<'a, A: 'a + Clone>: 'a + Clone
type SharedAny<'a, A: 'a + Send + Sync + Clone>: 'a + Send + Sync + Clone
where
Self: 'a;
fn share<'a, A: 'a + Clone>(fa: Self::FAny<'a, A>) -> Self::SharedAny<'a, A>
fn share<'a, A: 'a + Send + Sync + Clone>(fa: Self::FAny<'a, A>) -> Self::SharedAny<'a, A>
where
Self: 'a;
fn unshare<'a, A: 'a + Clone>(sa: Self::SharedAny<'a, A>) -> Self::FAny<'a, A>
fn unshare<'a, A: 'a + Send + Sync + Clone>(sa: Self::SharedAny<'a, A>) -> Self::FAny<'a, A>
where
Self: 'a;
}
pub trait SharedFunctor<'a>: WeakFunctor<'a> {
type Shared<A: 'a + Clone>: 'a + Clone;
type Shared<A: 'a + Send + Sync + Clone>: 'a + Send + Sync + Clone;
fn share<A: 'a + Clone>(fa: Self::F<A>) -> Self::Shared<A>;
fn share<A: 'a + Send + Sync + Clone>(fa: Self::F<A>) -> Self::Shared<A>;
fn unshare<A: 'a + Clone>(sa: Self::Shared<A>) -> Self::F<A>;
fn unshare<A: 'a + Send + Sync + Clone>(sa: Self::Shared<A>) -> Self::F<A>;
}
impl<'a, T: 'a + SharedFunctorAny> SharedFunctor<'a> for T {
type Shared<A: 'a + Clone> = T::SharedAny<'a, A>;
type Shared<A: 'a + Send + Sync + Clone> = T::SharedAny<'a, A>;
fn share<A: 'a + Clone>(fa: Self::F<A>) -> Self::Shared<A> {
fn share<A: 'a + Send + Sync + Clone>(fa: Self::F<A>) -> Self::Shared<A> {
T::share(fa)
}
fn unshare<A: 'a + Clone>(sa: Self::Shared<A>) -> Self::F<A> {
fn unshare<A: 'a + Send + Sync + Clone>(sa: Self::Shared<A>) -> Self::F<A> {
T::unshare(sa)
}
}

View File

@ -2,7 +2,7 @@ use super::tests::*;
use super::*;
pub trait FunctorTestSuite<'a>: WeakFunctor<'a> + Eqr<'a> {
fn sample<A: 'a, F: FnMut(&'a dyn Fn(A) -> Self::F<A>)>(f: F);
fn sample<A: 'a + Send, F: FnMut(&'a (dyn Send + Sync + Fn(A) -> Self::F<A>))>(f: F);
}
pub fn functor_follows_laws<'a, T: Functor<'a> + FunctorTestSuite<'a>>() -> R {

View File

@ -27,7 +27,11 @@ impl R {
}
pub trait Eqr<'a>: WeakFunctor<'a> {
fn eqr<A: PartialEq + Debug + 'a>(name: &'a str, left: Self::F<A>, right: Self::F<A>) -> R;
fn eqr<A: 'a + Send + PartialEq + Debug>(
name: &'a str,
left: Self::F<A>,
right: Self::F<A>,
) -> R;
}
pub fn eqr<T: PartialEq + Debug>(name: &str, left: T, right: T) -> R {
@ -87,7 +91,7 @@ impl AddAssign<R> for R {
}
}
pub fn fmap_respects_identity<'a, T: Functor<'a> + Eqr<'a>, A: 'a + Debug + PartialEq>(
pub fn fmap_respects_identity<'a, T: Functor<'a> + Eqr<'a>, A: 'a + Send + Debug + PartialEq>(
fa0: impl Fn() -> T::F<A>,
) -> R {
T::eqr("identity: fmap id == id", T::fmap(fa0(), |a| a), fa0())
@ -96,12 +100,12 @@ pub fn fmap_respects_identity<'a, T: Functor<'a> + Eqr<'a>, A: 'a + Debug + Part
pub fn fmap_respects_composition<
'a,
T: Functor<'a> + Eqr<'a>,
A: 'a,
B: 'a,
C: 'a + Debug + PartialEq,
A: 'a + Send,
B: 'a + Send,
C: 'a + Send + Debug + PartialEq,
>(
f: impl 'a + Copy + Fn(B) -> C,
g: impl 'a + Copy + Fn(A) -> B,
f: impl 'a + Send + Copy + Fn(B) -> C,
g: impl 'a + Send + Copy + Fn(A) -> B,
fa0: impl Fn() -> T::F<A>,
) -> R {
T::eqr(
@ -111,7 +115,7 @@ pub fn fmap_respects_composition<
)
}
pub fn seq_respects_identity<'a, T: Applicative<'a> + Eqr<'a>, A: 'a + Debug + PartialEq>(
pub fn seq_respects_identity<'a, T: Applicative<'a> + Eqr<'a>, A: 'a + Send + Debug + PartialEq>(
fa0: impl Fn() -> T::F<A>,
) -> R {
T::eqr(
@ -124,11 +128,11 @@ pub fn seq_respects_identity<'a, T: Applicative<'a> + Eqr<'a>, A: 'a + Debug + P
pub fn seq_respects_composition<
'a,
T: Applicative<'a> + Eqr<'a>,
A: 'a,
B: 'a,
C: 'a + Debug + PartialEq,
F: 'a + Fn(B) -> C,
G: 'a + Fn(A) -> B,
A: 'a + Send,
B: 'a + Send,
C: 'a + Send + Debug + PartialEq,
F: 'a + Send + Fn(B) -> C,
G: 'a + Send + Fn(A) -> B,
>(
ff0: impl Fn() -> T::F<F>,
fg0: impl Fn() -> T::F<G>,
@ -147,8 +151,13 @@ pub fn seq_respects_composition<
)
}
pub fn seq_is_homomorphic<'a, T: Applicative<'a> + Eqr<'a>, A: 'a, B: 'a + Debug + PartialEq>(
f: impl 'a + Fn(A) -> B,
pub fn seq_is_homomorphic<
'a,
T: Applicative<'a> + Eqr<'a>,
A: 'a + Send,
B: 'a + Send + Debug + PartialEq,
>(
f: impl 'a + Send + Fn(A) -> B,
a0: impl Fn() -> A,
) -> R {
T::eqr(
@ -161,12 +170,12 @@ pub fn seq_is_homomorphic<'a, T: Applicative<'a> + Eqr<'a>, A: 'a, B: 'a + Debug
pub fn seq_respects_interchange<
'a,
T: Applicative<'a> + Eqr<'a>,
A: 'a,
B: 'a + Debug + PartialEq,
F: 'a + Fn(A) -> B,
A: 'a + Send,
B: 'a + Send + Debug + PartialEq,
F: 'a + Send + Fn(A) -> B,
>(
ff0: impl Fn() -> T::F<F>,
a0: impl 'a + Fn() -> A,
a0: impl 'a + Send + Fn() -> A,
) -> R {
T::eqr(
"interchange: u <*> pure y = pure ($ y) <*> u",
@ -178,9 +187,9 @@ pub fn seq_respects_interchange<
pub fn seq_can_be_expressed_via_la2<
'a,
T: Applicative<'a> + Eqr<'a>,
A: 'a,
B: 'a + Debug + PartialEq,
F: 'a + Fn(A) -> B,
A: 'a + Send,
B: 'a + Send + Debug + PartialEq,
F: 'a + Send + Fn(A) -> B,
>(
ff0: impl Fn() -> T::F<F>,
fa0: impl Fn() -> T::F<A>,
@ -195,10 +204,10 @@ pub fn seq_can_be_expressed_via_la2<
pub fn fmap_can_be_expressed_via_seq<
'a,
T: Applicative<'a> + Eqr<'a>,
A: 'a,
B: 'a + Debug + PartialEq,
A: 'a + Send,
B: 'a + Send + Debug + PartialEq,
>(
f: impl 'a + Copy + Fn(A) -> B,
f: impl 'a + Send + Copy + Fn(A) -> B,
fa0: impl Fn() -> T::F<A>,
) -> R {
T::eqr(
@ -211,8 +220,8 @@ pub fn fmap_can_be_expressed_via_seq<
pub fn discard_can_be_expressed_via_seq_or_la2<
'a,
T: Applicative<'a> + Eqr<'a>,
A: 'a,
B: 'a + Debug + PartialEq,
A: 'a + Send,
B: 'a + Send + Debug + PartialEq,
>(
fa0: impl 'a + Fn() -> T::F<A>,
fb0: impl 'a + Fn() -> T::F<B>,
@ -228,8 +237,13 @@ pub fn discard_can_be_expressed_via_seq_or_la2<
)
}
pub fn bind_respects_left_identity<'a, T: Monad<'a> + Eqr<'a>, A: 'a, B: 'a + Debug + PartialEq>(
f: impl 'a + Fn(A) -> T::F<B>,
pub fn bind_respects_left_identity<
'a,
T: Monad<'a> + Eqr<'a>,
A: 'a + Send,
B: 'a + Send + Debug + PartialEq,
>(
f: impl 'a + Send + Fn(A) -> T::F<B>,
a0: impl Fn() -> A,
) -> R {
T::eqr(
@ -239,7 +253,11 @@ pub fn bind_respects_left_identity<'a, T: Monad<'a> + Eqr<'a>, A: 'a, B: 'a + De
)
}
pub fn bind_respects_right_identity<'a, T: Monad<'a> + Eqr<'a>, A: 'a + Debug + PartialEq>(
pub fn bind_respects_right_identity<
'a,
T: Monad<'a> + Eqr<'a>,
A: 'a + Send + Debug + PartialEq,
>(
fa0: impl Fn() -> T::F<A>,
) -> R {
T::eqr(
@ -249,10 +267,16 @@ pub fn bind_respects_right_identity<'a, T: Monad<'a> + Eqr<'a>, A: 'a + Debug +
)
}
pub fn bind_is_associative<'a, T: Monad<'a> + Eqr<'a>, A: 'a, B: 'a, C: 'a + Debug + PartialEq>(
f: impl 'a + Clone + Fn(B) -> T::F<C>,
g: impl 'a + Clone + Fn(A) -> T::F<B>,
fa0: impl 'a + Fn() -> T::F<A>,
pub fn bind_is_associative<
'a,
T: Monad<'a> + Eqr<'a>,
A: 'a + Send,
B: 'a + Send,
C: 'a + Send + Debug + PartialEq,
>(
f: impl 'a + Send + Clone + Fn(B) -> T::F<C>,
g: impl 'a + Send + Clone + Fn(A) -> T::F<B>,
fa0: impl Fn() -> T::F<A>,
) -> R {
T::eqr(
r"associativity: m >>= (\x -> k x >>= h) = (m >>= k) >>= h",
@ -264,12 +288,12 @@ pub fn bind_is_associative<'a, T: Monad<'a> + Eqr<'a>, A: 'a, B: 'a, C: 'a + Deb
pub fn seq_can_be_expressed_via_bind<
'a,
T: Monad<'a> + Eqr<'a>,
A: 'a,
B: 'a + Debug + PartialEq,
F: 'a + Fn(A) -> B,
A: 'a + Send,
B: 'a + Send + Debug + PartialEq,
F: 'a + Send + Fn(A) -> B,
>(
ff0: impl Fn() -> T::F<F>,
fa0: impl 'a + Fn() -> T::F<A>,
fa0: impl 'a + Send + Fn() -> T::F<A>,
) -> R {
T::eqr(
r"seq via bind: m1 <*> m2 = m1 >>= (\x1 -> m2 >>= (\x2 -> pure (x1 x2)))",
@ -281,11 +305,11 @@ pub fn seq_can_be_expressed_via_bind<
pub fn fmap_can_be_expressed_via_bind<
'a,
T: Monad<'a> + Eqr<'a>,
A: 'a,
B: 'a + Debug + PartialEq,
A: 'a + Send,
B: 'a + Send + Debug + PartialEq,
>(
f: impl 'a + Copy + Fn(A) -> B,
fa0: impl 'a + Fn() -> T::F<A>,
f: impl 'a + Send + Copy + Fn(A) -> B,
fa0: impl Fn() -> T::F<A>,
) -> R {
T::eqr(
"fmap via bind: fmap f xs = xs >>= return . f",

View File

@ -1,12 +1,12 @@
use super::WeakFunctor;
pub trait WeakFunctorAny {
pub trait WeakFunctorAny: Send {
/// Type of the wrapped value.
type FAny<'a, A: 'a>: 'a
type FAny<'a, A: 'a + Send>: 'a + Send
where
Self: 'a;
}
impl<'a, T: ?Sized + 'a + WeakFunctorAny> WeakFunctor<'a> for T {
type F<A: 'a> = T::FAny<'a, A>;
type F<A: 'a + Send> = T::FAny<'a, A>;
}

View File

@ -1,4 +1,4 @@
use std::{fmt::Display, marker::PhantomData, rc::Rc};
use std::{fmt::Display, marker::PhantomData, sync::Arc};
use crate::flow::{
binary::{balancing::*, bound::*, *},
@ -20,7 +20,7 @@ impl<A: Display> Display for Node<A> {
}
struct Reference<A> {
node: Rc<Node<A>>,
node: Arc<Node<A>>,
}
impl<A> Clone for Reference<A> {
@ -76,11 +76,11 @@ impl<A> Clone for Trees<A> {
}
}
impl<'a, A: 'a> FunctorContext<'a> for Trees<A> {
impl<'a, A: 'a + Send> FunctorContext<'a> for Trees<A> {
type T = instances::solo::SoloInstance;
}
impl<'a, A: 'a + Ord + Clone> BinaryTrees<'a> for Trees<A> {
impl<'a, A: 'a + Send + Sync + Ord + Clone> BinaryTrees<'a> for Trees<A> {
type Node = Node<A>;
type Reference = Reference<A>;
@ -114,17 +114,17 @@ impl<'a, A: 'a + Ord + Clone> BinaryTrees<'a> for Trees<A> {
}
}
impl<'a, A: 'a + Ord + Clone> BinaryTreesHeight<'a> for Trees<A> {
impl<'a, A: 'a + Send + Sync + Ord + Clone> BinaryTreesHeight<'a> for Trees<A> {
fn height(&self, tree: &Self::Tree) -> u64 {
tree.height
}
fn height_error<T: 'a>(&self, error: HeightError) -> BTWrap<'a, Self, T> {
fn height_error<T: 'a + Send>(&self, error: HeightError) -> BTWrap<'a, Self, T> {
panic!("{error}")
}
}
impl<'a, A: 'a + Ord + Clone> BinaryTreesEmpty<'a> for Trees<A> {
impl<'a, A: 'a + Send + Sync + Ord + Clone> BinaryTreesEmpty<'a> for Trees<A> {
fn empty(&self) -> Self::Tree {
Tree {
reference: None,
@ -141,7 +141,7 @@ impl<'a, A: 'a + Ord + Clone> BinaryTreesEmpty<'a> for Trees<A> {
}
}
impl<'a, A: 'a + Ord + Clone> BinaryTreesTryJoin<'a> for Trees<A> {
impl<'a, A: 'a + Send + Sync + Ord + Clone> BinaryTreesTryJoin<'a> for Trees<A> {
fn try_join(
&self,
tl: Self::Tree,
@ -152,17 +152,17 @@ impl<'a, A: 'a + Ord + Clone> BinaryTreesTryJoin<'a> for Trees<A> {
}
}
impl<'a, A: 'a + Ord + Clone> BinaryTreesUnbalanced<'a> for Trees<A> {
impl<'a, A: 'a + Send + Sync + Ord + Clone> BinaryTreesUnbalanced<'a> for Trees<A> {
fn tree_of_with_height(&self, node: Self::Node, height: u64) -> BTWrap<'a, Self, Self::Tree> {
Tree {
reference: Some(Reference {
node: Rc::new(node),
node: Arc::new(node),
}),
height,
}
}
fn balancing_error<T: 'a>(&self, _error: BalancingError) -> BTWrap<'a, Self, T> {
fn balancing_error<T: 'a + Send>(&self, _error: BalancingError) -> BTWrap<'a, Self, T> {
panic!("balancing error")
}
@ -171,8 +171,11 @@ impl<'a, A: 'a + Ord + Clone> BinaryTreesUnbalanced<'a> for Trees<A> {
}
}
impl<'a, A: 'a + Ord + Clone> BinaryTreesBindable<'a> for Trees<A> {
fn bounds_error<T: 'a>(&self, _error: bounds::BoundsError<Self::Key>) -> BTWrap<'a, Self, T> {
impl<'a, A: 'a + Send + Sync + Ord + Clone> BinaryTreesBindable<'a> for Trees<A> {
fn bounds_error<T: 'a + Send>(
&self,
_error: bounds::BoundsError<Self::Key>,
) -> BTWrap<'a, Self, T> {
panic!("bounds violated");
}
}

View File

@ -2,7 +2,7 @@
//!
//! Intended for testing.
use std::{fmt::Display, rc::*};
use std::{fmt::Display, sync::Arc};
use crate::flow::traversible::*;
use crate::func::*;
@ -20,24 +20,24 @@ impl PartialEq for UnbalancedData {
}
}
pub struct UnbalancedNode<'a, T: Monad<'a>, A: 'a> {
cl: Rc<UnbalancedTree<'a, T, A>>,
cr: Rc<UnbalancedTree<'a, T, A>>,
pub struct UnbalancedNode<'a, T: Monad<'a>, A: 'a + Send + Sync> {
cl: Arc<UnbalancedTree<'a, T, A>>,
cr: Arc<UnbalancedTree<'a, T, A>>,
key: A,
}
pub type UnbalancedResolution<'a, T, A> = Wrap<'a, Rc<UnbalancedNode<'a, T, A>>, T>;
pub type UnbalancedResolution<'a, T, A> = Wrap<'a, Arc<UnbalancedNode<'a, T, A>>, T>;
pub struct UnbalancedReference<'a, T: Monad<'a>, A: 'a>(
Box<dyn 'a + Fn() -> UnbalancedResolution<'a, T, A>>,
pub struct UnbalancedReference<'a, T: Monad<'a>, A: 'a + Send + Sync>(
Box<dyn 'a + Send + Sync + Fn() -> UnbalancedResolution<'a, T, A>>,
);
pub enum UnbalancedTree<'a, T: Monad<'a>, A: 'a> {
pub enum UnbalancedTree<'a, T: Monad<'a>, A: 'a + Send + Sync> {
Leaf,
Node(Rc<UnbalancedReference<'a, T, A>>),
Node(Arc<UnbalancedReference<'a, T, A>>),
}
impl<'a, T: Monad<'a>, A: 'a + Display> Display for UnbalancedNode<'a, T, A>
impl<'a, T: Monad<'a>, A: 'a + Send + Sync + Display> Display for UnbalancedNode<'a, T, A>
where
UnbalancedReference<'a, T, A>: std::fmt::Display,
{
@ -46,7 +46,7 @@ where
}
}
impl<'a, T: Monad<'a>, A: 'a + Display> Display for UnbalancedTree<'a, T, A>
impl<'a, T: Monad<'a>, A: 'a + Send + Sync + Display> Display for UnbalancedTree<'a, T, A>
where
UnbalancedReference<'a, T, A>: std::fmt::Display,
{
@ -58,13 +58,15 @@ where
}
}
impl<'a, A: 'a + Display> Display for UnbalancedReference<'a, instances::solo::SoloInstance, A> {
impl<'a, A: 'a + Send + Sync + Display> Display
for UnbalancedReference<'a, instances::solo::SoloInstance, A>
{
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "{}", self.0())
}
}
impl<'a, A: 'a + Display> Display
impl<'a, A: 'a + Send + Sync + Display> Display
for UnbalancedReference<'a, instances::result::ResultInstance<()>, A>
{
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
@ -75,24 +77,24 @@ impl<'a, A: 'a + Display> Display
}
}
impl<'a, T: Monad<'a>, A: 'a + Clone> TraversibleBinaryNode<'a, T, A, UnbalancedData>
impl<'a, T: Monad<'a>, A: 'a + Send + Sync + Clone> TraversibleBinaryNode<'a, T, A, UnbalancedData>
for UnbalancedNode<'a, T, A>
{
fn split(&self) -> Split<'a, T, A, UnbalancedData> {
(self.cl.clone(), self.cr.clone(), self.key.clone())
}
fn to_tree(self: Rc<Self>) -> Rc<dyn TraversibleBinaryTree<'a, T, A, UnbalancedData>> {
Rc::new(UnbalancedTree::Node(Rc::new(UnbalancedReference(
fn to_tree(self: Arc<Self>) -> Arc<dyn TraversibleBinaryTree<'a, T, A, UnbalancedData>> {
Arc::new(UnbalancedTree::Node(Arc::new(UnbalancedReference(
Box::new(move || T::pure(self.clone())),
))))
}
}
impl<'a, T: Monad<'a>, A: 'a + Clone> TraversibleBinaryReference<'a, T, A, UnbalancedData>
for UnbalancedReference<'a, T, A>
impl<'a, T: Monad<'a>, A: 'a + Send + Sync + Clone>
TraversibleBinaryReference<'a, T, A, UnbalancedData> for UnbalancedReference<'a, T, A>
{
fn resolve(&self) -> Wrap<'a, Rc<dyn TraversibleBinaryNode<'a, T, A, UnbalancedData>>, T> {
fn resolve(&self) -> Wrap<'a, Arc<dyn TraversibleBinaryNode<'a, T, A, UnbalancedData>>, T> {
<T as Functor>::fmap(self.0(), |rc| rc as _)
}
@ -101,10 +103,10 @@ impl<'a, T: Monad<'a>, A: 'a + Clone> TraversibleBinaryReference<'a, T, A, Unbal
}
}
impl<'a, T: Monad<'a>, A: 'a + Clone> TraversibleBinaryTree<'a, T, A, UnbalancedData>
impl<'a, T: Monad<'a>, A: 'a + Send + Sync + Clone> TraversibleBinaryTree<'a, T, A, UnbalancedData>
for UnbalancedTree<'a, T, A>
{
fn refer(&self) -> Option<Rc<dyn TraversibleBinaryReference<'a, T, A, UnbalancedData>>> {
fn refer(&self) -> Option<Arc<dyn TraversibleBinaryReference<'a, T, A, UnbalancedData>>> {
match self {
Self::Leaf => None,
Self::Node(reference) => Some(reference.clone()),
@ -113,39 +115,42 @@ impl<'a, T: Monad<'a>, A: 'a + Clone> TraversibleBinaryTree<'a, T, A, Unbalanced
}
type WrapType<'a, T, A> = Box<
dyn 'a + Fn(Rc<UnbalancedNode<'a, T, A>>) -> Box<dyn Fn() -> UnbalancedResolution<'a, T, A>>,
dyn 'a
+ Fn(
Arc<UnbalancedNode<'a, T, A>>,
) -> Box<dyn Send + Sync + Fn() -> UnbalancedResolution<'a, T, A>>,
>;
pub struct UnbalancedConstructor<'a, T: Monad<'a>, A: 'a> {
pub struct UnbalancedConstructor<'a, T: Monad<'a>, A: 'a + Send + Sync> {
wrap: WrapType<'a, T, A>,
}
impl<'a, T: Monad<'a>, A: 'a> UnbalancedConstructor<'a, T, A> {
pub fn rc(wrap: WrapType<'a, T, A>) -> Rc<Self> {
impl<'a, T: Monad<'a>, A: 'a + Send + Sync> UnbalancedConstructor<'a, T, A> {
pub fn rc(wrap: WrapType<'a, T, A>) -> Arc<Self> {
Self { wrap }.into()
}
pub fn leaf(&self) -> Rc<UnbalancedTree<'a, T, A>> {
pub fn leaf(&self) -> Arc<UnbalancedTree<'a, T, A>> {
UnbalancedTree::Leaf.into()
}
pub fn node(
self: &Rc<Self>,
cl: Rc<UnbalancedTree<'a, T, A>>,
self: &Arc<Self>,
cl: Arc<UnbalancedTree<'a, T, A>>,
key: A,
cr: Rc<UnbalancedTree<'a, T, A>>,
) -> Rc<UnbalancedTree<'a, T, A>> {
let node = Rc::new(UnbalancedNode { cl, cr, key });
cr: Arc<UnbalancedTree<'a, T, A>>,
) -> Arc<UnbalancedTree<'a, T, A>> {
let node = Arc::new(UnbalancedNode { cl, cr, key });
let ctr = self.clone();
UnbalancedTree::Node(Rc::new(UnbalancedReference((ctr.wrap)(node)))).into()
UnbalancedTree::Node(Arc::new(UnbalancedReference((ctr.wrap)(node)))).into()
}
#[cfg(test)]
pub fn from_slice<R: 'a + rand::Rng>(
self: &Rc<Self>,
self: &Arc<Self>,
rng: &mut R,
slice: &[A],
) -> Rc<UnbalancedTree<'a, T, A>>
) -> Arc<UnbalancedTree<'a, T, A>>
where
A: 'a + Clone,
{
@ -175,7 +180,7 @@ mod tests {
#[test]
fn test_simple_slices() {
let ctr: Rc<UnbalancedConstructor<instances::result::ResultInstance<()>, _>> =
let ctr: Arc<UnbalancedConstructor<instances::result::ResultInstance<()>, _>> =
UnbalancedConstructor::rc(Box::new(|node| Box::new(move || Ok(node.clone()))));
let mut rng = rand::thread_rng();
let t_set = ctr.from_slice(&mut rng, &[0]);
@ -207,7 +212,7 @@ mod tests {
#[test]
fn test_random_slices() {
let ctr: Rc<UnbalancedConstructor<instances::result::ResultInstance<()>, _>> =
let ctr: Arc<UnbalancedConstructor<instances::result::ResultInstance<()>, _>> =
UnbalancedConstructor::rc(Box::new(|node| Box::new(move || Ok(node.clone()))));
let mut rng = rand::thread_rng();
for _ in 0..1000 {
@ -256,7 +261,7 @@ mod tests {
#[test]
fn trace_one_slice() {
let ctr: Rc<UnbalancedConstructor<TracedMonad, _>> =
let ctr: Arc<UnbalancedConstructor<TracedMonad, _>> =
UnbalancedConstructor::rc(Box::new(|node| {
Box::new(move || TracedMonad::pure(node.clone()).after_resolution())
}));

View File

@ -18,7 +18,7 @@ mod regular;
mod resolution;
mod resolver_origin;
use std::{error::Error, rc::Rc};
use std::{error::Error, sync::Arc};
use crate::func::context::*;
use crate::func::*;
@ -48,7 +48,7 @@ pub use self::resolution::{
pub type Wrapped<'a, Ctx, A> = WrapC<'a, A, Ctx>;
/// [Mentionable] base.
pub trait MentionableBase<'a, Ctx: Context<'a>>: 'a + Serializable + Sized {
pub trait MentionableBase<'a, Ctx: Context<'a>>: 'a + Send + Sync + Serializable + Sized {
/// Type of the associated factory.
type Fctr: FactoryBase<'a, Ctx, Mtbl = Self>;
@ -104,7 +104,7 @@ pub trait FactoryBase<'a, Ctx: Context<'a>>: 'a + Send + Sync + Clone {
/// Type of the associated objects.
type Mtbl: MentionableBase<'a, Ctx, Fctr = Self>;
/// Type of an error that [`FactoryParse::deserialize`] can fail with.
type ParseError: 'a + Error;
type ParseError: 'a + Send + Error;
}
/// [Factory] that allows parsing consuming the parser.
@ -141,6 +141,6 @@ pub trait FactoryExt<'a, Ctx: Context<'a>>: FactoryParse<'a, Ctx> {
fn parse_slice(
&self,
slice: &[u8],
resolver: &Rc<dyn Resolver<'a, Ctx>>,
resolver: &Arc<dyn Resolver<'a, Ctx>>,
) -> ParseResult<'a, Ctx, Self>;
}

View File

@ -44,7 +44,7 @@ pub(super) trait InliningAddresses<E>: Stream {
fn inext_point<'a, Ctx: Context<'a>, A: MentionableBase<'a, Ctx>>(
self,
addresses: &mut Addresses,
resolver: Rc<dyn Resolver<'a, Ctx>>,
resolver: Arc<dyn Resolver<'a, Ctx>>,
factory: A::Fctr,
err: impl FnOnce(&[u8]) -> E,
) -> Result<(Point<'a, Ctx, A>, Self), E> {
@ -58,7 +58,7 @@ impl<E, D: ?Sized + Stream> InliningAddresses<E> for D {}
fn _parse_slice<'a, Ctx: Context<'a>, F: FactoryParse<'a, Ctx>>(
factory: &F,
slice: &[u8],
resolver: &Rc<dyn Resolver<'a, Ctx>>,
resolver: &Arc<dyn Resolver<'a, Ctx>>,
) -> ParseResult<'a, Ctx, F> {
let mut deserializer = SliceDeserializer::from(slice);
let mentionable = factory.deserialize(&mut DeCtxT {
@ -78,7 +78,7 @@ impl<'a, Ctx: Context<'a>, F: FactoryParse<'a, Ctx>> FactoryExt<'a, Ctx> for F {
fn parse_slice(
&self,
slice: &[u8],
resolver: &Rc<dyn Resolver<'a, Ctx>>,
resolver: &Arc<dyn Resolver<'a, Ctx>>,
) -> ParseResult<'a, Ctx, Self> {
_parse_slice::<Ctx, _>(self, slice, resolver)
}

View File

@ -9,7 +9,7 @@ pub trait Context<'a>: FallibleCtx<'a, T = Self::_Tm> {
type D: Diagnostic<'a, Self::T>;
/// Type to represent resolution errors mainly arising in [`Resolver::resolve`].
type LookupError: 'a + Error;
type LookupError: 'a + Send + Error;
/// Get [type@Hash] of a slice, mostly for use in [`Point`].
fn hash(s: &[u8]) -> Hash;

View File

@ -2,7 +2,7 @@ use super::*;
pub(super) struct DeCtxT<'a: 'c, 'c, Ctx: Context<'a>> {
pub deserializer: &'c mut dyn Deserializer,
pub resolver: &'c Rc<dyn Resolver<'a, Ctx>>,
pub resolver: &'c Arc<dyn Resolver<'a, Ctx>>,
pub addresses: &'c mut Addresses,
}
@ -13,7 +13,7 @@ pub(super) trait DeCtx<'a, Ctx: Context<'a>> {
fn next_address(&mut self) -> Result<Address, &[u8]>;
fn resolver(&self) -> Rc<dyn Resolver<'a, Ctx>>;
fn resolver(&self) -> Arc<dyn Resolver<'a, Ctx>>;
fn ad(&mut self) -> (&mut Addresses, &mut dyn Deserializer);
}
@ -31,7 +31,7 @@ impl<'a: 'c, 'c, Ctx: Context<'a>> DeCtx<'a, Ctx> for DeCtxT<'a, 'c, Ctx> {
self.addresses.next(self.deserializer)
}
fn resolver(&self) -> Rc<dyn Resolver<'a, Ctx>> {
fn resolver(&self) -> Arc<dyn Resolver<'a, Ctx>> {
self.resolver.clone()
}

View File

@ -38,7 +38,7 @@ impl<'a: 'c, 'c, Ctx: Context<'a>> InCtx<'a, Ctx> for Demoted<'a, 'c, Ctx> {
Ok((point, Self(dectx)))
}
fn iresolver(&self) -> Rc<dyn Resolver<'a, Ctx>> {
fn iresolver(&self) -> Arc<dyn Resolver<'a, Ctx>> {
self.0.iresolver()
}

View File

@ -1,17 +1,17 @@
use crate::func::Monad;
/// Basic support for tracing events across the execution.
pub trait Diagnostic<'a, T: Monad<'a>> {
pub trait Diagnostic<'a, T: Monad<'a>>: 'a + Send {
/// Specify that the evaluation happens after a specific event.
fn after<'b, A: 'a>(fa: T::F<A>, event: impl 'b + FnOnce() -> String) -> T::F<A>
fn after<'b, A: 'a + Send>(fa: T::F<A>, event: impl 'b + FnOnce() -> String) -> T::F<A>
where
'a: 'b;
/// Specify that the evaluation happens before a specific event.
fn before<'b, A: 'a>(fa: T::F<A>, event: impl 'b + FnOnce() -> String) -> T::F<A>
fn before<'b, A: 'a + Send>(fa: T::F<A>, event: impl 'b + FnOnce() -> String) -> T::F<A>
where
'a: 'b;
/// Label the evaluation step as a specific named action.
fn wrapped<'b, A: 'a>(fa: T::F<A>, event: impl 'b + FnOnce() -> String) -> T::F<A>
fn wrapped<'b, A: 'a + Send>(fa: T::F<A>, event: impl 'b + FnOnce() -> String) -> T::F<A>
where
'a: 'b;
}

View File

@ -19,7 +19,7 @@ pub trait InCtx<'a, Ctx: Context<'a>>: Stream {
}
/// Clone the reference to the current [Resolver].
fn iresolver(&self) -> Rc<dyn Resolver<'a, Ctx>>;
fn iresolver(&self) -> Arc<dyn Resolver<'a, Ctx>>;
/// Return [Demoted] version of the context.
fn demote<'d>(self) -> Demoted<'a, 'd, Ctx>
@ -59,7 +59,7 @@ impl<'a: 'c, 'c, Ctx: Context<'a>> InCtx<'a, Ctx> for &'c mut dyn DeCtx<'a, Ctx>
}
}
fn iresolver(&self) -> Rc<dyn Resolver<'a, Ctx>> {
fn iresolver(&self) -> Arc<dyn Resolver<'a, Ctx>> {
self.resolver()
}

View File

@ -1,17 +1,17 @@
use super::*;
/// Represents a potentially resolvable [`Mentionable`].
pub trait Origin<'a, Ctx: Context<'a>>: 'a {
pub trait Origin<'a, Ctx: Context<'a>>: 'a + Send + Sync {
/// Type of the associated object.
type Mtbl: MentionableBase<'a, Ctx>;
/// Clone the associated factory.
fn factory(&self) -> OFctr<'a, Ctx, Self>;
/// Try resolving the value.
fn resolve(self: Rc<Self>) -> Resolution<'a, Ctx, Self::Mtbl>
fn resolve(self: Arc<Self>) -> Resolution<'a, Ctx, Self::Mtbl>
where
OFctr<'a, Ctx, Self>: FactoryParse<'a, Ctx>;
/// Try resolving the bytes. Should avoid parsing the value.
fn resolve_bytes(self: Rc<Self>) -> HashResolution<'a, Ctx>;
fn resolve_bytes(self: Arc<Self>) -> HashResolution<'a, Ctx>;
}
/// Type of the [`Factory`] associated with the [`Origin`].
@ -19,16 +19,16 @@ pub type OFctr<'a, Ctx, O> = Fctr<'a, Ctx, <O as Origin<'a, Ctx>>::Mtbl>;
/// [`OriginMap::resolve_map`].
pub trait OriginMap<'a, Ctx: Context<'a>>: Origin<'a, Ctx> {
fn ref_resolve(self: &Rc<Self>) -> Resolution<'a, Ctx, Self::Mtbl>
fn ref_resolve(self: &Arc<Self>) -> Resolution<'a, Ctx, Self::Mtbl>
where
OFctr<'a, Ctx, Self>: FactoryParse<'a, Ctx>,
{
self.clone().resolve()
}
fn resolve_map<T>(
self: &Rc<Self>,
f: impl 'a + FnOnce(ResolutionResult<'a, Ctx, Self::Mtbl>) -> T,
fn resolve_map<T: 'a + Send>(
self: &Arc<Self>,
f: impl 'a + Send + FnOnce(ResolutionResult<'a, Ctx, Self::Mtbl>) -> T,
) -> Wrapped<'a, Ctx, T>
where
OFctr<'a, Ctx, Self>: FactoryParse<'a, Ctx>,

View File

@ -7,7 +7,7 @@ pub struct Point<'a, Ctx: Context<'a>, A: MentionableBase<'a, Ctx>> {
/// and its topology ([`MentionableTop::topology`]).
pub point: Hash,
/// [Origin] used in [`Point::resolve`].
pub origin: Rc<dyn Origin<'a, Ctx, Mtbl = A>>,
pub origin: Arc<dyn Origin<'a, Ctx, Mtbl = A>>,
}
impl<'a, Ctx: Context<'a>, A: MentionableBase<'a, Ctx>> PartialEq for Point<'a, Ctx, A> {
@ -36,9 +36,9 @@ where
}
/// Resolve the object, then map the [ResolutionResult].
pub fn resolve_map<B: 'a>(
pub fn resolve_map<B: 'a + Send>(
&self,
f: impl 'a + FnOnce(ResolutionResult<'a, Ctx, A>) -> B,
f: impl 'a + Send + FnOnce(ResolutionResult<'a, Ctx, A>) -> B,
) -> Wrapped<'a, Ctx, B> {
self.origin.resolve_map(f)
}

View File

@ -27,7 +27,7 @@ pub type ResolutionFailure<'a, Ctx, A> =
ResolutionError<LookupError<'a, Ctx>, ParseErrorA<'a, Ctx, A>>;
/// Result yielded by [`Origin`].
pub type ResolutionResult<'a, Ctx, A> = Result<Rc<A>, ResolutionFailure<'a, Ctx, A>>;
pub type ResolutionResult<'a, Ctx, A> = Result<Arc<A>, ResolutionFailure<'a, Ctx, A>>;
/// Wrapped result returned by [`Origin`].
pub type Resolution<'a, Ctx, A> = Wrapped<'a, Ctx, ResolutionResult<'a, Ctx, A>>;
@ -35,7 +35,7 @@ pub type Resolution<'a, Ctx, A> = Wrapped<'a, Ctx, ResolutionResult<'a, Ctx, A>>
/// Underlying [`Result`] of [`HashResolution`].
/// In case of success, contains byte data and the resolver for points appearing inside that data.
pub type HashResolutionResult<'a, Ctx> =
Result<(Vec<u8>, Rc<dyn Resolver<'a, Ctx>>), LookupError<'a, Ctx>>;
Result<(Vec<u8>, Arc<dyn Resolver<'a, Ctx>>), LookupError<'a, Ctx>>;
/// Shorthand for the type of values returned by [`Resolver::resolve`].
pub type HashResolution<'a, Ctx> = Wrapped<'a, Ctx, HashResolutionResult<'a, Ctx>>;
@ -49,19 +49,19 @@ pub struct Address {
}
/// Trait representing the "rainbow table" behaviour.
pub trait Resolver<'a, Ctx: Context<'a>>: 'a {
pub trait Resolver<'a, Ctx: Context<'a>>: 'a + Send + Sync {
/// Successfully returned value should be the inverse of the point passed
/// with topology header ([`MentionableTop::topology()`]) omitted.
fn resolve(self: Rc<Self>, address: Address) -> HashResolution<'a, Ctx>;
fn resolve(self: Arc<Self>, address: Address) -> HashResolution<'a, Ctx>;
}
/// [`ResolverMap::resolve_map`].
pub trait ResolverMap<'a, Ctx: Context<'a>>: Resolver<'a, Ctx> {
/// Resolve the [Address], then map the [`HashResolutionResult`].
fn resolve_map<T>(
self: Rc<Self>,
fn resolve_map<T: 'a + Send>(
self: Arc<Self>,
address: Address,
f: impl 'a + FnOnce(HashResolutionResult<'a, Ctx>) -> T,
f: impl 'a + Send + FnOnce(HashResolutionResult<'a, Ctx>) -> T,
) -> Wrapped<'a, Ctx, T> {
Ctx::fmap(self.resolve(address), f)
}

View File

@ -8,11 +8,11 @@ where
pub fn from_address(
address: Address,
factory: A::Fctr,
resolver: Rc<dyn Resolver<'a, Ctx>>,
resolver: Arc<dyn Resolver<'a, Ctx>>,
) -> Self {
Point {
point: address.point,
origin: Rc::new(ResolverOrigin {
origin: Arc::new(ResolverOrigin {
r_factory: factory,
r_address: address,
r_resolver: resolver,
@ -24,11 +24,11 @@ where
struct ResolverOrigin<'a, Ctx: Context<'a>, F: FactoryBase<'a, Ctx>> {
r_factory: F,
r_address: Address,
r_resolver: Rc<dyn Resolver<'a, Ctx>>,
r_resolver: Arc<dyn Resolver<'a, Ctx>>,
}
fn _resolve_origin<'a, Ctx: Context<'a>, F: FactoryParse<'a, Ctx>>(
origin: Rc<ResolverOrigin<'a, Ctx, F>>,
origin: Arc<ResolverOrigin<'a, Ctx, F>>,
) -> Resolution<'a, Ctx, F::Mtbl> {
origin
.r_resolver
@ -39,7 +39,7 @@ fn _resolve_origin<'a, Ctx: Context<'a>, F: FactoryParse<'a, Ctx>>(
.r_factory
.parse_slice(&src, &resolver)
.map_err(ResolutionError::Parse)?;
Ok(Rc::new(mentionable))
Ok(Arc::new(mentionable))
})
}
@ -50,14 +50,14 @@ impl<'a, Ctx: Context<'a>, F: FactoryBase<'a, Ctx>> Origin<'a, Ctx> for Resolver
self.r_factory.clone()
}
fn resolve(self: Rc<Self>) -> Resolution<'a, Ctx, Self::Mtbl>
fn resolve(self: Arc<Self>) -> Resolution<'a, Ctx, Self::Mtbl>
where
F: FactoryParse<'a, Ctx>,
{
_resolve_origin(self)
}
fn resolve_bytes(self: Rc<Self>) -> HashResolution<'a, Ctx> {
fn resolve_bytes(self: Arc<Self>) -> HashResolution<'a, Ctx> {
self.r_resolver.clone().resolve(self.r_address)
}
}

View File

@ -16,7 +16,7 @@ pub mod tracing;
pub mod typeless;
mod wrapped_origin;
use std::{error::Error, fmt::Display, rc::Rc};
use std::{error::Error, fmt::Display, sync::Arc};
use crate::func::*;
use crate::mode::*;
@ -44,12 +44,12 @@ impl<S: Serializable> SerializableExt for S {
/// [`ResolverExt::into_rc`].
pub trait ResolverExt<'a, Ctx: Context<'a>>: Resolver<'a, Ctx> {
/// Wrap the resolver into [`Rc`].
fn into_rc(self) -> Rc<dyn Resolver<'a, Ctx>>;
/// Wrap the resolver into [`Arc`].
fn into_rc(self) -> Arc<dyn Resolver<'a, Ctx>>;
}
impl<'a, Ctx: Context<'a>, R: Resolver<'a, Ctx>> ResolverExt<'a, Ctx> for R {
fn into_rc(self) -> Rc<dyn Resolver<'a, Ctx>> {
Rc::new(self)
fn into_rc(self) -> Arc<dyn Resolver<'a, Ctx>> {
Arc::new(self)
}
}

View File

@ -83,8 +83,8 @@ impl<'a> CastError<'a> {
}
impl<'a, Ctx: CastCtx<'a>> CastResolver<'a, Ctx> {
fn rc(points: Vec<Point<'a, Ctx, TypelessMentionable<'a, Ctx>>>) -> Rc<dyn Resolver<'a, Ctx>> {
Rc::new(Self { points })
fn rc(points: Vec<Point<'a, Ctx, TypelessMentionable<'a, Ctx>>>) -> Arc<dyn Resolver<'a, Ctx>> {
Arc::new(Self { points })
}
fn _get_point(
@ -138,7 +138,7 @@ fn map_resolved<'a, Ctx: CastCtx<'a>>(
}
impl<'a, Ctx: CastCtx<'a>> Resolver<'a, Ctx> for CastResolver<'a, Ctx> {
fn resolve(self: Rc<Self>, address: Address) -> HashResolution<'a, Ctx> {
fn resolve(self: Arc<Self>, address: Address) -> HashResolution<'a, Ctx> {
let point = match self.get_point(address) {
Ok(point) => point,
Err(cast_error) => return cast_error.pure::<Ctx>(),
@ -151,7 +151,7 @@ impl<'a, Ctx: CastCtx<'a>> TypelessMentionable<'a, Ctx> {
pub fn cast_full<A: Mentionable<'a, Ctx>>(
&self,
factory: A::Fctr,
map_resolver: impl FnOnce(Rc<dyn Resolver<'a, Ctx>>) -> Rc<dyn Resolver<'a, Ctx>>,
map_resolver: impl FnOnce(Arc<dyn Resolver<'a, Ctx>>) -> Arc<dyn Resolver<'a, Ctx>>,
) -> ParseResultA<'a, Ctx, A> {
factory.parse_slice(
&self.bytes(),
@ -183,20 +183,20 @@ fn cast_resolved<'a, Ctx: CastCtx<'a>, A: Mentionable<'a, Ctx>>(
.map_err(ResolutionError::Lookup)?
.cast(factory)
.map_err(ResolutionError::Parse)
.map(Rc::new)
.map(Arc::new)
}
fn cast_resolve<'a, Ctx: CastCtx<'a>, A: Mentionable<'a, Ctx>>(
typeless_origin: Rc<dyn Origin<'a, Ctx, Mtbl = TypelessMentionable<'a, Ctx>>>,
typeless_origin: Arc<dyn Origin<'a, Ctx, Mtbl = TypelessMentionable<'a, Ctx>>>,
factory: A::Fctr,
) -> Resolution<'a, Ctx, A> {
typeless_origin.resolve_map(|resolved| cast_resolved(resolved, factory))
}
fn cast_origin<'a, Ctx: CastCtx<'a>, A: Mentionable<'a, Ctx>>(
typeless_origin: Rc<dyn Origin<'a, Ctx, Mtbl = TypelessMentionable<'a, Ctx>>>,
typeless_origin: Arc<dyn Origin<'a, Ctx, Mtbl = TypelessMentionable<'a, Ctx>>>,
factory: A::Fctr,
) -> Rc<dyn Origin<'a, Ctx, Mtbl = A>> {
) -> Arc<dyn Origin<'a, Ctx, Mtbl = A>> {
let origin_rb = typeless_origin.clone();
wrapped_origin(
factory.clone(),
@ -209,7 +209,7 @@ impl<'a, Ctx: CastCtx<'a>> Point<'a, Ctx, TypelessMentionable<'a, Ctx>> {
fn cast_origin<A: Mentionable<'a, Ctx>>(
&self,
factory: A::Fctr,
) -> Rc<dyn Origin<'a, Ctx, Mtbl = A>> {
) -> Arc<dyn Origin<'a, Ctx, Mtbl = A>> {
let typeless_origin = self.origin.clone();
cast_origin(typeless_origin, factory)
}

View File

@ -236,7 +236,7 @@ where
#[cfg(test)]
mod tests {
use std::rc::Rc;
use std::sync::Arc;
use crate::rstd::{atomic::plain::*, atomic_object::*, tracing::*};
use crate::testing::{counted::*, traced::*, *};
@ -290,7 +290,7 @@ mod tests {
let stack: T<TestContextCounted> = make_stack();
let count = stack.clone().vec().count();
assert_eq!(count, 0);
let stack: T<TestContextCounted> = Rc::new(stack).delay()?;
let stack: T<TestContextCounted> = Arc::new(stack).delay()?;
let count = stack.clone().vec().count();
assert_eq!(count, 3);
Ok(())
@ -303,7 +303,7 @@ mod tests {
assert_eq!(traced.length(), 0);
assert_eq!(traced.width(), 0);
assert_eq!(format!("{}", traced.effect), ".");
let stack: T<TestContextTraced> = Rc::new(stack).trace()?;
let stack: T<TestContextTraced> = Arc::new(stack).trace()?;
let traced = stack.clone().vec();
assert_eq!(traced.length(), 3);
assert_eq!(traced.width(), 1);
@ -318,7 +318,7 @@ mod tests {
assert_eq!(rendered.length(), 0);
assert_eq!(rendered.width(), 0);
assert_eq!(format!("{}", rendered), ".");
let stack: T<TestContextTraced> = Rc::new(stack).trace()?;
let stack: T<TestContextTraced> = Arc::new(stack).trace()?;
let rendered = stack.clone().vec().render();
assert_eq!(rendered.length(), 3);
assert_eq!(rendered.width(), 1);

View File

@ -1,4 +1,4 @@
use std::{marker::PhantomData, rc::Rc};
use std::{marker::PhantomData, sync::Arc};
use crate::{
flow::{
@ -56,16 +56,26 @@ impl<'a, Ctx: Context<'a>, A: Mentionable<'a, Ctx>, E: 'a> From<HeightError>
}
}
pub type TreeContext2<'a, Ctx, A, C, E> = TreeContext<(Rc<C>, Fctr<'a, Ctx, A>), (Ctx, A, E)>;
pub type TreeContext2<'a, Ctx, A, C, E> = TreeContext<(Arc<C>, Fctr<'a, Ctx, A>), (Ctx, A, E)>;
impl<'a, Ctx: Context<'a>, A: Mentionable<'a, Ctx> + Clone, C: 'a + Comparator<A>, E: 'a>
FunctorContext<'a> for TreeContext2<'a, Ctx, A, C, E>
impl<
'a,
Ctx: Context<'a>,
A: Mentionable<'a, Ctx> + Clone,
C: 'a + Comparator<A>,
E: 'a + Send,
> FunctorContext<'a> for TreeContext2<'a, Ctx, A, C, E>
{
type T = FallibleMonad<'a, Ctx, TreeContextError<'a, Ctx, A, E>>;
}
impl<'a, Ctx: Context<'a>, A: Mentionable<'a, Ctx> + Clone, C: 'a + Comparator<A>, E: 'a>
BinaryTrees<'a> for TreeContext2<'a, Ctx, A, C, E>
impl<
'a,
Ctx: Context<'a>,
A: Mentionable<'a, Ctx> + Clone,
C: 'a + Comparator<A>,
E: 'a + Send,
> BinaryTrees<'a> for TreeContext2<'a, Ctx, A, C, E>
{
type Node = Node<'a, Ctx, A>;
@ -107,8 +117,13 @@ impl<'a, Ctx: Context<'a>, A: Mentionable<'a, Ctx> + Clone, C: 'a + Comparator<A
}
}
impl<'a, Ctx: Context<'a>, A: Mentionable<'a, Ctx> + Clone, C: 'a + Comparator<A>, E: 'a>
BinaryTreesEmpty<'a> for TreeContext2<'a, Ctx, A, C, E>
impl<
'a,
Ctx: Context<'a>,
A: Mentionable<'a, Ctx> + Clone,
C: 'a + Comparator<A>,
E: 'a + Send,
> BinaryTreesEmpty<'a> for TreeContext2<'a, Ctx, A, C, E>
{
fn empty(&self) -> Self::Tree {
Tree {
@ -126,14 +141,19 @@ impl<'a, Ctx: Context<'a>, A: Mentionable<'a, Ctx> + Clone, C: 'a + Comparator<A
}
}
impl<'a, Ctx: Context<'a>, A: Mentionable<'a, Ctx> + Clone, C: 'a + Comparator<A>, E: 'a>
BinaryTreesHeight<'a> for TreeContext2<'a, Ctx, A, C, E>
impl<
'a,
Ctx: Context<'a>,
A: Mentionable<'a, Ctx> + Clone,
C: 'a + Comparator<A>,
E: 'a + Send,
> BinaryTreesHeight<'a> for TreeContext2<'a, Ctx, A, C, E>
{
fn height(&self, tree: &Self::Tree) -> u64 {
tree.height
}
fn height_error<T: 'a>(&self, error: HeightError) -> BTWrap<'a, Self, T> {
fn height_error<T: 'a + Send>(&self, error: HeightError) -> BTWrap<'a, Self, T> {
Self::fail(error.into())
}
}
@ -167,15 +187,20 @@ impl<'a, Ctx: Context<'a>, A: Mentionable<'a, Ctx>, E: 'a> From<BoundsError<A>>
}
}
impl<'a, Ctx: Context<'a>, A: Mentionable<'a, Ctx> + Clone, C: 'a + Comparator<A>, E: 'a>
BinaryTreesUnbalanced<'a> for TreeContext2<'a, Ctx, A, C, WrappedExtra<BalancingError, E>>
impl<
'a,
Ctx: Context<'a>,
A: Mentionable<'a, Ctx> + Clone,
C: 'a + Comparator<A>,
E: 'a + Send,
> BinaryTreesUnbalanced<'a> for TreeContext2<'a, Ctx, A, C, WrappedExtra<BalancingError, E>>
{
fn tree_of_with_height(&self, node: Self::Node, height: u64) -> BTWrap<'a, Self, Self::Tree> {
let node = Nullable::from(node);
Self::pure(Tree { node, height })
}
fn balancing_error<T: 'a>(&self, error: BalancingError) -> BTWrap<'a, Self, T> {
fn balancing_error<T: 'a + Send>(&self, error: BalancingError) -> BTWrap<'a, Self, T> {
Self::fail(error.into())
}
@ -184,10 +209,15 @@ impl<'a, Ctx: Context<'a>, A: Mentionable<'a, Ctx> + Clone, C: 'a + Comparator<A
}
}
impl<'a, Ctx: Context<'a>, A: Mentionable<'a, Ctx> + Clone, C: 'a + Comparator<A>, E: 'a>
BinaryTreesBindable<'a> for TreeContext2<'a, Ctx, A, C, WrappedExtra<BoundsError<A>, E>>
impl<
'a,
Ctx: Context<'a>,
A: Mentionable<'a, Ctx> + Clone,
C: 'a + Comparator<A>,
E: 'a + Send,
> BinaryTreesBindable<'a> for TreeContext2<'a, Ctx, A, C, WrappedExtra<BoundsError<A>, E>>
{
fn bounds_error<T: 'a>(&self, error: BoundsError<Self::Key>) -> BTWrap<'a, Self, T> {
fn bounds_error<T: 'a + Send>(&self, error: BoundsError<Self::Key>) -> BTWrap<'a, Self, T> {
Self::fail(error.into())
}
}

View File

@ -1,13 +1,13 @@
use std::rc::Rc;
use std::sync::Arc;
use crate::rcore::*;
use crate::rstd::{singular::*, *};
pub trait Inject<'a, Ctx: Context<'a>>: 'a + Sized {
fn inject<A: 'a>(&self, fa: Wrapped<'a, Ctx, A>) -> Wrapped<'a, Ctx, A>;
pub trait Inject<'a, Ctx: Context<'a>>: 'a + Send + Sync + Sized {
fn inject<A: 'a + Send>(&self, fa: Wrapped<'a, Ctx, A>) -> Wrapped<'a, Ctx, A>;
fn inject_mentionable<A: Mentionable<'a, Ctx>>(
self: Rc<Self>,
self: Arc<Self>,
a: &A,
) -> ParseResultA<'a, Ctx, A> {
let factory = a.factory();
@ -20,12 +20,12 @@ pub trait Inject<'a, Ctx: Context<'a>>: 'a + Sized {
}
struct InjectedResolver<'a, Ctx: Context<'a>, F: Inject<'a, Ctx>> {
resolver: Rc<dyn Resolver<'a, Ctx>>,
inject: Rc<F>,
resolver: Arc<dyn Resolver<'a, Ctx>>,
inject: Arc<F>,
}
impl<'a, Ctx: Context<'a>, F: Inject<'a, Ctx>> Resolver<'a, Ctx> for InjectedResolver<'a, Ctx, F> {
fn resolve(self: Rc<Self>, address: Address) -> HashResolution<'a, Ctx> {
fn resolve(self: Arc<Self>, address: Address) -> HashResolution<'a, Ctx> {
let inject = self.inject.clone();
self.inject.inject(
self.resolver

View File

@ -30,7 +30,7 @@ pub trait StaticPairSerializable {
///
/// Note: [`StaticPair::FA`] requires [`InliningFactory`] be implemented.
pub trait StaticPair<'a, Ctx: Context<'a>>:
'a + StaticPairSerializable<SA = Self::A, SB = Self::B> + Sized
'a + Send + Sync + StaticPairSerializable<SA = Self::A, SB = Self::B> + Sized
{
/// [Factory] data. May, depending on the usecase, include factory (factories) on the element(s).
type FactoryData: 'a + Send + Sync + Clone;
@ -43,7 +43,7 @@ pub trait StaticPair<'a, Ctx: Context<'a>>:
/// Second element's factory.
type FB: FactoryBase<'a, Ctx, Mtbl = Self::B> + ParseMode;
/// See [`FactoryBase::ParseError`].
type ParseError: 'a + Error;
type ParseError: 'a + Send + Error;
/// Borrow both elements' factories.
fn factories(factory_data: &Self::FactoryData) -> (&Self::FA, &Self::FB);
@ -266,7 +266,7 @@ pub trait StaticPairAtomic:
/// Second element's type. Must equal [`StaticPairSerializable::SB`].
type B: AtomicBase + ParseMode;
type AParseError: Error;
type AParseError: Error + Send;
/// Construct the atomic from the elements.
fn from_parsed(a: Self::A, b: Self::B) -> Result<Self, Self::AParseError>;
/// Regularise the error returned while parsing the first element.

View File

@ -1,4 +1,4 @@
use std::rc::Rc;
use std::sync::Arc;
use crate::func::context::*;
use crate::rcore::*;
@ -13,15 +13,15 @@ impl<'a, Ctx: Context<'a>, A: Mentionable<'a, Ctx>> Point<'a, Ctx, A> {
vec
}
fn from_fields(point: Hash, origin: Rc<dyn Origin<'a, Ctx, Mtbl = A>>) -> Self {
fn from_fields(point: Hash, origin: Arc<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, Rc::new(origin))
Self::from_fields(point, Arc::new(origin))
}
fn from_mentionable(mentionable: Rc<A>) -> Self {
fn from_mentionable(mentionable: Arc<A>) -> Self {
Self::from_values(
Ctx::hash(&Self::prepare_bytes_for_hashing(&mentionable)),
LocalOrigin::from(mentionable),
@ -29,7 +29,7 @@ impl<'a, Ctx: Context<'a>, A: Mentionable<'a, Ctx>> Point<'a, Ctx, A> {
}
}
struct LocalOrigin<A>(Rc<A>);
struct LocalOrigin<A>(Arc<A>);
impl<'a, Ctx: Context<'a>, A: Mentionable<'a, Ctx>> Origin<'a, Ctx> for LocalOrigin<A> {
type Mtbl = A;
@ -38,26 +38,26 @@ impl<'a, Ctx: Context<'a>, A: Mentionable<'a, Ctx>> Origin<'a, Ctx> for LocalOri
self.0.factory()
}
fn resolve(self: Rc<Self>) -> Resolution<'a, Ctx, Self::Mtbl> {
fn resolve(self: Arc<Self>) -> Resolution<'a, Ctx, Self::Mtbl> {
Ctx::pure(Ok(self.0.clone()))
}
fn resolve_bytes(self: Rc<Self>) -> HashResolution<'a, Ctx> {
fn resolve_bytes(self: Arc<Self>) -> HashResolution<'a, Ctx> {
Ctx::pure(Ok((
self.0.bytes(),
Rc::new(SingularResolver::from_mentionable(self.0.as_ref())),
Arc::new(SingularResolver::from_mentionable(self.0.as_ref())),
)))
}
}
impl<A> From<Rc<A>> for LocalOrigin<A> {
fn from(value: Rc<A>) -> Self {
impl<A> From<Arc<A>> for LocalOrigin<A> {
fn from(value: Arc<A>) -> Self {
LocalOrigin(value)
}
}
impl<'a, Ctx: Context<'a>, A: Mentionable<'a, Ctx>> From<Rc<A>> for Point<'a, Ctx, A> {
fn from(value: Rc<A>) -> Self {
impl<'a, Ctx: Context<'a>, A: Mentionable<'a, Ctx>> From<Arc<A>> for Point<'a, Ctx, A> {
fn from(value: Arc<A>) -> Self {
Self::from_mentionable(value)
}
}

View File

@ -73,7 +73,7 @@ impl<'a, Ctx: Context<'a>, A: Mentionable<'a, Ctx>> Nullable<'a, Ctx, Nullable<'
match self {
Self::Null(nullable_factory) => {
let NullableFactory { factory } = nullable_factory;
Ctx::pure(Ok(Rc::new(Nullable::Null(factory.clone()))))
Ctx::pure(Ok(Arc::new(Nullable::Null(factory.clone()))))
}
Self::NotNull(point) => point.resolve(),
}
@ -81,7 +81,7 @@ impl<'a, Ctx: Context<'a>, A: Mentionable<'a, Ctx>> Nullable<'a, Ctx, Nullable<'
}
impl<'a, Ctx: Context<'a>, A: Mentionable<'a, Ctx>> Nullable<'a, Ctx, A> {
fn from_mentionable(mentionable: Rc<A>) -> Self {
fn from_mentionable(mentionable: Arc<A>) -> Self {
Self::NotNull(mentionable.into())
}
@ -142,8 +142,8 @@ impl<F> AlwaysConstSize for NullableFactory<F> {
const _SIZE: usize = HASH_SIZE;
}
impl<'a, Ctx: Context<'a>, A: Mentionable<'a, Ctx>> From<Rc<A>> for Nullable<'a, Ctx, A> {
fn from(value: Rc<A>) -> Self {
impl<'a, Ctx: Context<'a>, A: Mentionable<'a, Ctx>> From<Arc<A>> for Nullable<'a, Ctx, A> {
fn from(value: Arc<A>) -> Self {
Self::from_mentionable(value)
}
}

View File

@ -1,8 +1,9 @@
use crate::rcore::*;
use crate::rstd::*;
trait SingularResolution<'a, Ctx: Context<'a>>: 'a {
fn singular(self: Rc<Self>) -> HashResolution<'a, Ctx>;
use super::*;
trait SingularResolution<'a, Ctx: Context<'a>>: 'a + Send + Sync {
fn singular(self: Arc<Self>) -> HashResolution<'a, Ctx>;
fn s_hash(&self) -> Hash;
}
@ -10,7 +11,7 @@ trait SingularResolution<'a, Ctx: Context<'a>>: 'a {
impl<'a, Ctx: Context<'a>, A: Mentionable<'a, Ctx>> SingularResolution<'a, Ctx>
for Point<'a, Ctx, A>
{
fn singular(self: Rc<Self>) -> HashResolution<'a, Ctx> {
fn singular(self: Arc<Self>) -> HashResolution<'a, Ctx> {
self.origin.clone().resolve_bytes()
}
@ -20,7 +21,7 @@ impl<'a, Ctx: Context<'a>, A: Mentionable<'a, Ctx>> SingularResolution<'a, Ctx>
}
pub struct SingularResolver<'a, Ctx: Context<'a>> {
points: Vec<Rc<dyn SingularResolution<'a, Ctx>>>,
points: Vec<Arc<dyn SingularResolution<'a, Ctx>>>,
}
impl<'a, Ctx: Context<'a>> SingularResolver<'a, Ctx> {
@ -32,7 +33,7 @@ impl<'a, Ctx: Context<'a>> SingularResolver<'a, Ctx> {
}
impl<'a, Ctx: Context<'a>> Resolver<'a, Ctx> for SingularResolver<'a, Ctx> {
fn resolve(self: Rc<Self>, address: Address) -> HashResolution<'a, Ctx> {
fn resolve(self: Arc<Self>, address: Address) -> HashResolution<'a, Ctx> {
let point = self.points.get(address.index).unwrap_or_else(|| {
panic!(
"singularity out-of-bounds: {}/{}",
@ -52,8 +53,8 @@ impl<'a, Ctx: Context<'a>> Resolver<'a, Ctx> for SingularResolver<'a, Ctx> {
}
}
impl<'a, Ctx: Context<'a>> PointsVisitor<'a, Ctx> for Vec<Rc<dyn SingularResolution<'a, Ctx>>> {
impl<'a, Ctx: Context<'a>> PointsVisitor<'a, Ctx> for Vec<Arc<dyn SingularResolution<'a, Ctx>>> {
fn visit<A: Mentionable<'a, Ctx>>(&mut self, point: &Point<'a, Ctx, A>) {
self.push(Rc::new(point.clone()) as _);
self.push(Arc::new(point.clone()) as _);
}
}

View File

@ -5,7 +5,7 @@ use super::*;
struct TracedInject;
impl<'a, Ctx: Context<'a, _Tm = TracedInstance>> Inject<'a, Ctx> for TracedInject {
fn inject<A: 'a>(&self, fa: Wrapped<'a, Ctx, A>) -> Wrapped<'a, Ctx, A> {
fn inject<A: 'a + Send>(&self, fa: Wrapped<'a, Ctx, A>) -> Wrapped<'a, Ctx, A> {
fa.after_resolution()
}
}
@ -20,7 +20,7 @@ pub trait Traceable<'a, Ctx: Context<'a, _Tm = TracedInstance>>:
/// [^extra]: applying [`Traceable::trace`] multiple times
/// might affect the trace in undesireable ways
fn trace(&self) -> ParseResultA<'a, Ctx, Self> {
Rc::new(TracedInject).inject_mentionable(self)
Arc::new(TracedInject).inject_mentionable(self)
}
}

View File

@ -5,7 +5,7 @@
use super::{cast::*, wrapped_origin::*, *};
use crate::mode::*;
type TypelessSerialize<'a> = dyn 'a + Fn(&mut dyn Serializer);
type TypelessSerialize<'a> = dyn 'a + Send + Sync + Fn(&mut dyn Serializer);
/// See [`Point::typeless`].
pub struct TypelessMentionable<'a, Ctx: Context<'a>> {
@ -15,7 +15,7 @@ pub struct TypelessMentionable<'a, Ctx: Context<'a>> {
t_points: Vec<Point<'a, Ctx, TypelessMentionable<'a, Ctx>>>,
}
type TypelessParsed<'a, Ctx> = Result<TypelessMentionable<'a, Ctx>, Box<dyn 'a + Error>>;
type TypelessParsed<'a, Ctx> = Result<TypelessMentionable<'a, Ctx>, Box<dyn 'a + Send + Error>>;
trait Tde<'a, Ctx: Context<'a>>: 'a + Send + Sync {
fn clone_box(&self) -> TdeBox<'a, Ctx>;
@ -82,7 +82,7 @@ impl<'a, Ctx: Context<'a>> Clone for TypelessFactory<'a, Ctx> {
/// See [`Point::typeless`]/[`TypelessFactory`].
#[derive(Debug)]
pub struct TypelessError<'a>(Box<dyn 'a + Error>);
pub struct TypelessError<'a>(Box<dyn 'a + Send + Error>);
impl<'a> Display for TypelessError<'a> {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
@ -113,7 +113,7 @@ impl<'a, Ctx: Context<'a>> CRegularFactory<'a, Ctx> for TypelessFactory<'a, Ctx>
}
impl<'a, Ctx: CastCtx<'a>> TypelessMentionable<'a, Ctx> {
pub fn from_typed<A: Mentionable<'a, Ctx>>(mentionable: Rc<A>) -> Self {
pub fn from_typed<A: Mentionable<'a, Ctx>>(mentionable: Arc<A>) -> Self {
let factory = TypelessFactory::from_typed(mentionable.factory());
let topology = mentionable.topology();
let points = mentionable.points_vec();
@ -137,7 +137,7 @@ impl<'a, Ctx: CastCtx<'a>, F: Factory<'a, Ctx>> Tde<'a, Ctx> for F {
{
self.deserialize(demoted)
.map_err(|e| Box::new(e) as _)
.map(Rc::new)
.map(Arc::new)
.map(TypelessMentionable::from_typed)
}
}
@ -160,7 +160,7 @@ impl<'a, Ctx: CastCtx<'a>, F: Factory<'a, Ctx>> Tut<'a, Ctx> for F {
tail,
)
.map_err(TypelessError::from_typed)
.map(Rc::new)
.map(Arc::new)
.map(TypelessMentionable::from_typed)
}
}
@ -175,7 +175,7 @@ impl<'a, Ctx: CastCtx<'a>> TypelessFactory<'a, Ctx> {
}
impl<'a> TypelessError<'a> {
pub fn from_typed<E: 'a + Error>(error: E) -> Self {
pub fn from_typed<E: 'a + Send + Error>(error: E) -> Self {
TypelessError(Box::new(error))
}
}

View File

@ -4,10 +4,10 @@ use super::*;
pub fn wrapped_origin<'a, Ctx: Context<'a>, A: Mentionable<'a, Ctx>>(
factory: A::Fctr,
resolve: impl 'a + Fn() -> Resolution<'a, Ctx, A>,
resolve_bytes: impl 'a + Fn() -> HashResolution<'a, Ctx>,
) -> Rc<dyn Origin<'a, Ctx, Mtbl = A>> {
Rc::new(WrappedOrigin {
resolve: impl 'a + Send + Sync + Fn() -> Resolution<'a, Ctx, A>,
resolve_bytes: impl 'a + Send + Sync + Fn() -> HashResolution<'a, Ctx>,
) -> Arc<dyn Origin<'a, Ctx, Mtbl = A>> {
Arc::new(WrappedOrigin {
w_factory: factory,
w_resolve: Box::new(resolve),
w_resolve_bytes: Box::new(resolve_bytes),
@ -16,15 +16,15 @@ pub fn wrapped_origin<'a, Ctx: Context<'a>, A: Mentionable<'a, Ctx>>(
pub trait MappableOrigin<'a, Ctx: Context<'a>>: Origin<'a, Ctx> {
fn map<B: Mentionable<'a, Ctx>>(
self: Rc<Self>,
map_ok: impl 'a + Send + Sync + Clone + Fn(Rc<Self::Mtbl>) -> B,
self: Arc<Self>,
map_ok: impl 'a + Send + Sync + Clone + Fn(Arc<Self::Mtbl>) -> B,
map_err: impl 'a
+ Send
+ Sync
+ Clone
+ Fn(ParseError<'a, Ctx, OFctr<'a, Ctx, Self>>) -> ParseError<'a, Ctx, B::Fctr>,
map_factory: impl 'a + FnOnce(OFctr<'a, Ctx, Self>) -> B::Fctr,
) -> Rc<dyn Origin<'a, Ctx, Mtbl = B>>
) -> Arc<dyn Origin<'a, Ctx, Mtbl = B>>
where
OFctr<'a, Ctx, Self>: Factory<'a, Ctx, _Mtbl = Self::Mtbl>,
Self::Mtbl: MentionableTop<'a, Ctx>,
@ -41,27 +41,27 @@ pub trait MappableOrigin<'a, Ctx: Context<'a>>: Origin<'a, Ctx> {
}),
w_resolve_bytes: Box::new(move || origin_rb.clone().resolve_bytes()),
};
Rc::new(origin)
Arc::new(origin)
}
}
impl<'a, Ctx: Context<'a>, O: ?Sized + Origin<'a, Ctx>> MappableOrigin<'a, Ctx> for O {}
fn map_resolve<'a, Ctx: Context<'a>, A: Mentionable<'a, Ctx>, B: Mentionable<'a, Ctx>>(
resolve: impl 'a + Fn() -> Resolution<'a, Ctx, A>,
map_ok: impl 'a + Fn(Rc<A>) -> B,
map_err: impl 'a + Fn(ParseError<'a, Ctx, A::Fctr>) -> ParseError<'a, Ctx, B::Fctr>,
resolve: impl 'a + Send + Fn() -> Resolution<'a, Ctx, A>,
map_ok: impl 'a + Send + Fn(Arc<A>) -> B,
map_err: impl 'a + Send + Fn(ParseError<'a, Ctx, A::Fctr>) -> ParseError<'a, Ctx, B::Fctr>,
) -> Resolution<'a, Ctx, B> {
Ctx::fmap(resolve(), move |resolved| match resolved {
Ok(mentionable) => Ok(Rc::new(map_ok(mentionable))),
Ok(mentionable) => Ok(Arc::new(map_ok(mentionable))),
Err(e) => Err(e.map_parse(map_err)),
})
}
struct WrappedOrigin<'a, Ctx: Context<'a>, A: Mentionable<'a, Ctx>> {
w_factory: A::Fctr,
w_resolve: Box<dyn 'a + Fn() -> Resolution<'a, Ctx, A>>,
w_resolve_bytes: Box<dyn 'a + Fn() -> HashResolution<'a, Ctx>>,
w_resolve: Box<dyn 'a + Send + Sync + Fn() -> Resolution<'a, Ctx, A>>,
w_resolve_bytes: Box<dyn 'a + Send + Sync + Fn() -> HashResolution<'a, Ctx>>,
}
impl<'a, Ctx: Context<'a>, A: Mentionable<'a, Ctx>> Origin<'a, Ctx> for WrappedOrigin<'a, Ctx, A> {
@ -71,11 +71,11 @@ impl<'a, Ctx: Context<'a>, A: Mentionable<'a, Ctx>> Origin<'a, Ctx> for WrappedO
self.w_factory.clone()
}
fn resolve(self: Rc<Self>) -> Resolution<'a, Ctx, A> {
fn resolve(self: Arc<Self>) -> Resolution<'a, Ctx, A> {
(self.w_resolve)()
}
fn resolve_bytes(self: Rc<Self>) -> HashResolution<'a, Ctx> {
fn resolve_bytes(self: Arc<Self>) -> HashResolution<'a, Ctx> {
(self.w_resolve_bytes)()
}
}

View File

@ -1,7 +1,7 @@
pub mod counted;
pub mod traced;
use std::{error::Error, fmt::Display, rc::Rc};
use std::{error::Error, fmt::Display, sync::Arc};
use sha2::{Digest, Sha256};
@ -12,15 +12,15 @@ use crate::rstd::{cast::*, inject::*, typeless::*};
pub struct NoDiagnostic;
impl<'a, T: Monad<'a>> Diagnostic<'a, T> for NoDiagnostic {
fn after<'b, A>(fa: T::F<A>, _event: impl 'b + FnOnce() -> String) -> T::F<A> {
fn after<'b, A: 'a + Send>(fa: T::F<A>, _event: impl 'b + FnOnce() -> String) -> T::F<A> {
fa
}
fn before<'b, A>(fa: T::F<A>, _event: impl 'b + FnOnce() -> String) -> T::F<A> {
fn before<'b, A: 'a + Send>(fa: T::F<A>, _event: impl 'b + FnOnce() -> String) -> T::F<A> {
fa
}
fn wrapped<'b, A>(fa: T::F<A>, _event: impl 'b + FnOnce() -> String) -> T::F<A> {
fn wrapped<'b, A: 'a + Send>(fa: T::F<A>, _event: impl 'b + FnOnce() -> String) -> T::F<A> {
fa
}
}
@ -89,7 +89,7 @@ impl<'a> Context<'a> for TestContextPlain {
pub struct EmptyResolver;
impl<'a> Resolver<'a, TestContextPlain> for EmptyResolver {
fn resolve(self: std::rc::Rc<Self>, address: Address) -> HashResolution<'a, TestContextPlain> {
fn resolve(self: Arc<Self>, address: Address) -> HashResolution<'a, TestContextPlain> {
Err(TestLookupError::EmptyResolverAccess(address))
}
}
@ -97,13 +97,13 @@ impl<'a> Resolver<'a, TestContextPlain> for EmptyResolver {
struct EmptyInject;
impl<'a, Ctx: Context<'a>> Inject<'a, Ctx> for EmptyInject {
fn inject<A: 'a>(&self, fa: Wrapped<'a, Ctx, A>) -> Wrapped<'a, Ctx, A> {
fn inject<A: 'a + Send>(&self, fa: Wrapped<'a, Ctx, A>) -> Wrapped<'a, Ctx, A> {
fa
}
}
pub fn reparse<'a, A: Mentionable<'a, TestContextPlain>>(mentionable: Rc<A>) -> A {
Rc::new(EmptyInject)
pub fn reparse<'a, A: Mentionable<'a, TestContextPlain>>(mentionable: Arc<A>) -> A {
Arc::new(EmptyInject)
.inject_mentionable(mentionable.as_ref())
.expect("re-parsing failed")
}

View File

@ -61,7 +61,7 @@ impl<A> Counted<A> {
struct CountedInject;
impl<'a> Inject<'a, TestContextCounted> for CountedInject {
fn inject<A: 'a>(
fn inject<A: 'a + Send>(
&self,
fa: Wrapped<'a, TestContextCounted, A>,
) -> Wrapped<'a, TestContextCounted, A> {
@ -71,7 +71,7 @@ impl<'a> Inject<'a, TestContextCounted> for CountedInject {
pub trait Delayable<'a>: Mentionable<'a, TestContextCounted> + Sized {
fn delay(&self) -> ParseResultA<'a, TestContextCounted, Self> {
Rc::new(CountedInject).inject_mentionable(self)
Arc::new(CountedInject).inject_mentionable(self)
}
}