diff --git a/radn-derive/src/lib.rs b/radn-derive/src/lib.rs index a04d8ad..6af2736 100644 --- a/radn-derive/src/lib.rs +++ b/radn-derive/src/lib.rs @@ -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, { diff --git a/src/atomic.rs b/src/atomic.rs index 8944375..e10ffa2 100644 --- a/src/atomic.rs +++ b/src/atomic.rs @@ -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`], diff --git a/src/flow/binary.rs b/src/flow/binary.rs index cfe10fc..e67f2b8 100644 --- a/src/flow/binary.rs +++ b/src/flow/binary.rs @@ -18,10 +18,10 @@ pub type KeySplit<'a, BT> = (>::Tree, = 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; 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(&self, error: HeightError) -> BTWrap<'a, Self, T>; + fn height_error(&self, error: HeightError) -> BTWrap<'a, Self, T>; } pub trait BinaryTreesTryJoin<'a>: BinaryTrees<'a> { diff --git a/src/flow/binary/avl.rs b/src/flow/binary/avl.rs index 148da18..fc94329 100644 --- a/src/flow/binary/avl.rs +++ b/src/flow/binary/avl.rs @@ -50,10 +50,10 @@ pub trait BinaryTreesAvl<'a>: } } - fn assume_bind( + fn assume_bind( 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); diff --git a/src/flow/binary/balancing.rs b/src/flow/binary/balancing.rs index 4f59ca5..c48c637 100644 --- a/src/flow/binary/balancing.rs +++ b/src/flow/binary/balancing.rs @@ -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(&self, error: BalancingError) -> BTWrap<'a, Self, T>; + fn balancing_error(&self, error: BalancingError) -> BTWrap<'a, Self, T>; - fn balancing_bind( + fn balancing_bind( &self, ra: Result, 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(&self, error: HeightError) -> BTWrap<'a, Self, T> { + fn height_error(&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 { - fn bounds_error(&self, error: bounds::BoundsError) -> BTWrap<'a, Self, T> { + fn bounds_error( + &self, + error: bounds::BoundsError, + ) -> BTWrap<'a, Self, T> { self.0.bounds_error(error) } } diff --git a/src/flow/binary/bound.rs b/src/flow/binary/bound.rs index fefe201..5c67957 100644 --- a/src/flow/binary/bound.rs +++ b/src/flow/binary/bound.rs @@ -38,9 +38,9 @@ impl<'a, BT: FunctorContext<'a>> FunctorContext<'a> for BoundTrees { } pub trait BinaryTreesBindable<'a>: BinaryTrees<'a> { - fn bounds_error(&self, error: BoundsError) -> BTWrap<'a, Self, T>; + fn bounds_error(&self, error: BoundsError) -> BTWrap<'a, Self, T>; - fn bounds_bind( + fn bounds_bind( &self, ra: Result>, 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(&self, error: HeightError) -> BTWrap<'a, Self, T> { + fn height_error(&self, error: HeightError) -> BTWrap<'a, Self, T> { self.0.height_error(error) } } diff --git a/src/flow/comparator.rs b/src/flow/comparator.rs index 48941cc..902cbf2 100644 --- a/src/flow/comparator.rs +++ b/src/flow/comparator.rs @@ -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 { +pub trait Comparator: 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); mod rc_comparator_impl { use super::*; - use std::rc::Rc; + use std::sync::Arc; - impl> Comparator> for RcComparator { - fn compare(&self, kl: &Rc, kr: &Rc) -> Comparison { + impl> Comparator> for RcComparator { + fn compare(&self, kl: &Arc, kr: &Arc) -> Comparison { self.0.compare(kl, kr) } } diff --git a/src/flow/speculative.rs b/src/flow/speculative.rs index 4d3dbce..4c727df 100644 --- a/src/flow/speculative.rs +++ b/src/flow/speculative.rs @@ -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( + fn _speculative_a_wb( a: A, wb: WrapE<'a, B, E0, Self>, ) -> WrapE<'a, (A, B), Result, Self> { Self::map_err( as Functor>::fmap(wb, |b| (a, b)), Ok) } - fn _speculative_ra_wb( + fn _speculative_ra_wb( ra: Result, wb: WrapE<'a, B, E0, Self>, ) -> WrapE<'a, (A, B), Result, Self> { @@ -23,7 +23,7 @@ trait SpeculativeFailImpl<'a>: MonadFailAny<'a> { } } - fn _speculative_ra_rwb( + fn _speculative_ra_rwb( ra: Result, rwb: Result, E1>, ) -> WrapE<'a, (A, B), Result, Self> { @@ -33,7 +33,7 @@ trait SpeculativeFailImpl<'a>: MonadFailAny<'a> { } } - fn _speculative_ra_frwb( + fn _speculative_ra_frwb( ra: Result, frwb: Frwa<'a, B, E0, E1, Self>, ) -> WrapE<'a, (A, B), Result, Self> { @@ -42,14 +42,14 @@ trait SpeculativeFailImpl<'a>: MonadFailAny<'a> { })) } - fn _speculative_fra_wb( + fn _speculative_fra_wb( fra: Wrap<'a, Result, Self::T>, wb: WrapE<'a, B, E0, Self>, ) -> WrapE<'a, (A, B), E0, Self> { as ApplicativeTuple>::tuple((Self::stuff(fra), wb)) } - fn _speculative_wa_frwb( + fn _speculative_wa_frwb( wa: WrapE<'a, A, E0, Self>, frwb: Frwa<'a, B, E0, E1, Self>, ) -> WrapE<'a, (A, B), Result, Self> { @@ -67,7 +67,7 @@ trait SpeculativeFailImpl<'a>: MonadFailAny<'a> { )) } - fn _speculative_frwa_wb( + fn _speculative_frwa_wb( frwa: Frwa<'a, A, E0, E1, Self>, wb: WrapE<'a, B, E0, Self>, ) -> WrapE<'a, (A, B), Result, Self> { @@ -77,7 +77,7 @@ trait SpeculativeFailImpl<'a>: MonadFailAny<'a> { ) } - fn _speculative( + fn _speculative( wwa: Wwa<'a, A, E0, E1, Self>, wwb: Wwa<'a, B, E0, E1, Self>, ) -> WrapE<'a, (A, B), Result, Self> { @@ -98,7 +98,7 @@ trait SpeculativeFailImpl<'a>: MonadFailAny<'a> { } pub trait SpeculativeFail<'a>: MonadFailAny<'a> { - fn speculative( + fn speculative( wwa: Wwa<'a, A, E0, E1, Self>, wwb: Wwa<'a, B, E0, E1, Self>, ) -> WrapE<'a, (A, B), Result, Self> { diff --git a/src/flow/traversible.rs b/src/flow/traversible.rs index 81a371c..6beb6d2 100644 --- a/src/flow/traversible.rs +++ b/src/flow/traversible.rs @@ -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>, - Rc>, + Arc>, + Arc>, 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) -> Rc>; + fn to_tree(self: Arc) -> Arc>; } -pub trait TraversibleBinaryReference<'a, T: Monad<'a>, A: 'a, D: 'a + PartialEq>: 'a { - fn resolve(&self) -> Wrap<'a, Rc>, T>; +pub trait TraversibleBinaryReference<'a, T: Monad<'a>, A: 'a, D: 'a + PartialEq>: + 'a + Send + Sync +{ + fn resolve(&self) -> Wrap<'a, Arc>, 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>>; +pub trait TraversibleBinaryTree<'a, T: Monad<'a>, A: 'a, D: 'a + PartialEq>: + 'a + Send + Sync +{ + fn refer(&self) -> Option>>; } diff --git a/src/flow/traversible/algorithms/contains.rs b/src/flow/traversible/algorithms/contains.rs index 504d86d..fba955c 100644 --- a/src/flow/traversible/algorithms/contains.rs +++ b/src/flow/traversible/algorithms/contains.rs @@ -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, - n_set: Rc>, + n_set: Arc>, 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, - r_set: Rc>, + r_set: Arc>, 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, - t_set: Rc>, + t_set: Arc>, key: A, ) -> T::F<()> { match t_set.refer() { diff --git a/src/flow/traversible/algorithms/subset.rs b/src/flow/traversible/algorithms/subset.rs index 4f530ac..f82d566 100644 --- a/src/flow/traversible/algorithms/subset.rs +++ b/src/flow/traversible/algorithms/subset.rs @@ -6,16 +6,18 @@ fn and(_l: (), _r: ()) {} struct SubsetContext<'a, T: MonadFail<'a, ()>, A: 'a, D: 'a + PartialEq> { comparator: &'a dyn Comparator, - n_subset: Rc>, - n_superset: Rc>, + n_subset: Arc>, + n_superset: Arc>, k_l: Option, k_r: Option, - t_superl: Rc>, - t_superr: Rc>, + t_superl: Arc>, + t_superr: Arc>, 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(comparator: &dyn Comparator, k_r: &Option, 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, - n_subset: Rc>, - n_superset: Rc>, + n_subset: Arc>, + n_superset: Arc>, k_l: Option, k_r: Option, ) -> 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, - r_subset: Rc>, - r_superset: Rc>, + r_subset: Arc>, + r_superset: Arc>, k_l: Option, k_r: Option, ) -> 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>, - r_superset: Rc>, +fn r_subset_of_r_optimised<'a, T: MonadFail<'a, ()>, A: 'a + Send + Clone, D: 'a + PartialEq>( + r_subset: Arc>, + r_superset: Arc>, comparator: &'a dyn Comparator, k_l: Option, k_r: Option, @@ -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, - t_subset: Rc>, - t_superset: Rc>, + t_subset: Arc>, + t_superset: Arc>, k_l: Option, k_r: Option, ) -> T::F<()> { diff --git a/src/func.rs b/src/func.rs index b47a9a8..c5ba21e 100644 --- a/src/func.rs +++ b/src/func.rs @@ -30,8 +30,8 @@ pub use self::extensions::MonadExt; /// Part of Haskell's `Functor f` responsible for having `f a`. /// /// -pub trait WeakFunctor<'a>: 'a { - type F: 'a; +pub trait WeakFunctor<'a>: 'a + Send { + type F: 'a + Send; } pub type Wrap<'a, A, T> = >::F; @@ -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(fa: Self::F, f: impl 'a + FnOnce(A) -> B) -> Self::F; + fn fmap( + fa: Self::F, + f: impl 'a + Send + FnOnce(A) -> B, + ) -> Self::F; /// Equivalent of Haskell's `$>`/`<$`. - fn replace(fa: Self::F, b: B) -> Self::F { + fn replace(fa: Self::F, b: B) -> Self::F { Self::fmap(fa, |_| b) } /// Equivalent of Haskell's `void`. - fn void(fa: Self::F) -> Self::F<()> { + fn void(fa: Self::F) -> 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) -> Self::F; + fn pure(a: A) -> Self::F; } /// Part of [`Applicative`] responsible for Haskell's sequential application `<*>`. pub trait ApplicativeSeq<'a>: Functor<'a> { /// Equivalent of Haskell's `<*>`. - fn seq(ff: Self::F B>, fa: Self::F) -> Self::F; + fn seq( + ff: Self::F B>, + fa: Self::F, + ) -> Self::F; } /// Part of [`Applicative`] responsible for Haskell's result combination `listA2`. pub trait ApplicativeLA2<'a>: Functor<'a> { /// Equivalent of Haskell's `listA2`. - fn la2( + fn la2( fa: Self::F, fb: Self::F, - f: impl 'a + FnOnce(A, B) -> C, + f: impl 'a + Send + FnOnce(A, B) -> C, ) -> Self::F; } /// 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(fab: (Self::F, Self::F)) -> Self::F<(A, B)>; + fn tuple(fab: (Self::F, Self::F)) -> 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(fa: Self::F, fb: Self::F) -> Self::F { + fn discard_first(fa: Self::F, fb: Self::F) -> Self::F { Self::seq(Self::replace(fa, |b| b), fb) } /// Equivalent of Haskell's `<*`. - fn discard_second(fa: Self::F, fb: Self::F) -> Self::F { + fn discard_second(fa: Self::F, fb: Self::F) -> Self::F { 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(fa: Self::F, f: impl 'a + FnOnce(A) -> Self::F) -> Self::F; + fn bind( + fa: Self::F, + f: impl 'a + Send + FnOnce(A) -> Self::F, + ) -> Self::F; /// 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(f: impl Iterative<'a, T = Self, B = B>) -> Self::F; + fn iterate(f: impl Iterative<'a, T = Self, B = B>) -> Self::F; /// Equivalent of Haskell's `join`. - fn join(ffa: Self::F>) -> Self::F { + fn join(ffa: Self::F>) -> Self::F { Self::bind(ffa, |fa| fa) } } diff --git a/src/func/applicative_select.rs b/src/func/applicative_select.rs index d1bacaf..7e0ee78 100644 --- a/src/func/applicative_select.rs +++ b/src/func/applicative_select.rs @@ -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(T::F, 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(fa: Self::F, fb: Self::F) -> SelectedWrapped<'a, A, B, Self> { + fn select( + fa: Self::F, + fb: Self::F, + ) -> SelectedWrapped<'a, A, B, Self> { Self::fmap(fa, |a| Selected::A(a, fb)) } } pub trait ApplicativeSelectExt<'a>: ApplicativeSelect<'a> { /// Shorthand for [`Functor::fmap`]∘[`ApplicativeSelect::select`]. - fn select_map( + fn select_map( fa: Self::F, fb: Self::F, - f: impl 'a + FnOnce(Selected<'a, A, B, Self>) -> C, + f: impl 'a + Send + FnOnce(Selected<'a, A, B, Self>) -> C, ) -> Self::F { Self::fmap(Self::select(fa, fb), f) } diff --git a/src/func/context.rs b/src/func/context.rs index 9ce5484..5f658ac 100644 --- a/src/func/context.rs +++ b/src/func/context.rs @@ -2,28 +2,31 @@ use super::{fail::*, *}; pub type WrapC<'a, A, Ctx> = Wrap<'a, 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(fa: WrapC<'a, A, Self>, f: impl 'a + FnOnce(A) -> B) -> WrapC<'a, B, Self> + fn fmap( + fa: WrapC<'a, A, Self>, + f: impl 'a + Send + FnOnce(A) -> B, + ) -> WrapC<'a, B, Self> where Self::T: Functor<'a>, { ::fmap(fa, f) } - fn pure(a: A) -> WrapC<'a, A, Self> + fn pure(a: A) -> WrapC<'a, A, Self> where Self::T: Pure<'a>, { ::pure(a) } - fn bind( + fn bind( 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> { ::bind(fa, f) } - fn fail(e: E) -> WrapC<'a, A, Self> + fn fail(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(wa: FallibleWrapped<'a, Self, A, E>) -> WrapC<'a, Result, Self> { + fn unstuff( + wa: FallibleWrapped<'a, Self, A, E>, + ) -> WrapC<'a, Result, Self> { Self::Fallible::unstuff(wa) } /// Convert a wrapped result into a fallible wrapped. - fn stuff(fa: WrapC<'a, Result, Self>) -> FallibleWrapped<'a, Self, A, E> { + fn stuff( + fa: WrapC<'a, Result, Self>, + ) -> FallibleWrapped<'a, Self, A, E> { Self::Fallible::stuff(fa) } } diff --git a/src/func/controlflow.rs b/src/func/controlflow.rs index d7db7ea..315159c 100644 --- a/src/func/controlflow.rs +++ b/src/func/controlflow.rs @@ -6,14 +6,14 @@ use super::{weakfunctorany::WeakFunctorAny, Functor, Pure, WeakFunctor, Wrap}; pub(super) struct ControlFlowInstance(ControlFlow<(), C>); -impl WeakFunctorAny for ControlFlowInstance { - type FAny<'a, A: 'a> = ControlFlow +impl WeakFunctorAny for ControlFlowInstance { + type FAny<'a, A: 'a + Send> = ControlFlow where Self: 'a; } -impl<'a, C: 'a> Functor<'a> for ControlFlowInstance { - fn fmap(fa: Self::F, f: impl 'a + FnOnce(A) -> B) -> Self::F { +impl<'a, C: 'a + Send> Functor<'a> for ControlFlowInstance { + fn fmap(fa: Self::F, f: impl 'a + FnOnce(A) -> B) -> Self::F { 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 { } } -impl<'a, C: 'a> Pure<'a> for ControlFlowInstance { - fn pure(a: A) -> Self::F { +impl<'a, C: 'a + Send> Pure<'a> for ControlFlowInstance { + fn pure(a: A) -> Self::F { ControlFlow::Break(a) } } pub struct BindableMut(A, F, PhantomData, PhantomData); -impl<'a, T: ?Sized + Functor<'a>, A: 'a, B: 'a, F: 'a + FnMut(A) -> T::F>> - BindableMut +impl< + 'a, + T: ?Sized + Functor<'a>, + A: 'a + Send, + B: 'a + Send, + F: 'a + Send + FnMut(A) -> T::F>, + > BindableMut { 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>> - Iterative<'a> for BindableMut +impl< + 'a, + T: ?Sized + Functor<'a>, + A: 'a + Send, + B: 'a + Send, + F: 'a + Send + FnMut(A) -> T::F>, + > Iterative<'a> for BindableMut { 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. diff --git a/src/func/derivations.rs b/src/func/derivations.rs index d15bdfb..1276e64 100644 --- a/src/func/derivations.rs +++ b/src/func/derivations.rs @@ -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, +pub fn bind<'a, T: Monad<'a>, A: 'a + Send, B: 'a + Send>( + f: impl 'a + Send + FnOnce(A) -> T::F, ) -> 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( - f: impl 'a + FnOnce(A, B) -> C, + fn _la2_via_seq( + f: impl 'a + Send + FnOnce(A, B) -> C, fa: Self::F, fb: Self::F, ) -> Self::F { @@ -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( - ff: Self::F B>, + fn _seq_via_la2( + ff: Self::F B>, fa: Self::F, ) -> Self::F { 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((fa, fb): (Self::F, Self::F)) -> Self::F<(A, B)> { + fn _tuple_via_la2( + (fa, fb): (Self::F, Self::F), + ) -> Self::F<(A, B)> { Self::la2(fa, fb, |a, b| (a, b)) } } diff --git a/src/func/extensions.rs b/src/func/extensions.rs index 4405e2d..ffc5664 100644 --- a/src/func/extensions.rs +++ b/src/func/extensions.rs @@ -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( + fn iterate_mut( a: A, - f: impl 'a + FnMut(A) -> Self::F>, + f: impl 'a + Send + FnMut(A) -> Self::F>, ) -> Self::F { Self::iterate(BindableMut::new(a, f)) } - fn bind2( + fn bind2( fa: Self::F, fb: Self::F, - f: impl 'a + FnOnce(A, B) -> Self::F, + f: impl 'a + Send + FnOnce(A, B) -> Self::F, ) -> Self::F { Self::join(Self::la2(fa, fb, f)) } diff --git a/src/func/fail.rs b/src/func/fail.rs index 8280cfe..be6cb2f 100644 --- a/src/func/fail.rs +++ b/src/func/fail.rs @@ -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(e: E) -> Self::F; + fn fail(e: E) -> Self::F; } /// Equivalent of Haskell's `MonadFail`. Auto-implemented for all [`Fail`]`+`[`Monad`]. /// /// -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: MonadFail<'a, E> - where - E: 'a; + type W: MonadFail<'a, E>; /// Associated infallible [`Monad`]. type T: Monad<'a>; - fn unstuff(wa: WrapE<'a, A, E, Self>) -> Wrap<'a, Result, Self::T>; + fn unstuff( + wa: WrapE<'a, A, E, Self>, + ) -> Wrap<'a, Result, Self::T>; - fn stuff(fa: Wrap<'a, Result, Self::T>) -> WrapE<'a, A, E, Self>; + fn stuff( + fa: Wrap<'a, Result, Self::T>, + ) -> WrapE<'a, A, E, Self>; /// Equivalent of [`Result::map_err`]. - fn map_err( + fn map_err( 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( + fn bind_err( 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( + fn bind( wa: WrapE<'a, A, E0, Self>, - f: impl 'a + FnOnce(Result) -> WrapE<'a, B, E1, Self>, + f: impl 'a + Send + FnOnce(Result) -> WrapE<'a, B, E1, Self>, ) -> WrapE<'a, B, E1, Self> { Self::stuff(::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( + fn join( wwa: WrapE<'a, WrapE<'a, A, E0, Self>, E1, Self>, ) -> WrapE<'a, A, Result, Self> { Self::bind(wwa, |result| match result { @@ -73,7 +75,7 @@ pub trait MonadFailAny<'a>: 'a { } /// Lift the error. - fn rotate_out( + fn rotate_out( wa: WrapE<'a, Result, E0, Self>, ) -> WrapE<'a, A, Result, Self> { > 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, >::W>; pub trait MonadFailAnyExt<'a>: MonadFailAny<'a> { - fn pure(a: A) -> WrapE<'a, A, E, Self> { + fn pure(a: A) -> WrapE<'a, A, E, Self> { as Pure>::pure(a) } - fn fail(e: E) -> WrapE<'a, A, E, Self> { + fn fail(e: E) -> WrapE<'a, A, E, Self> { as Fail>::fail(e) } } diff --git a/src/func/instances/composition.rs b/src/func/instances/composition.rs index de0503f..b7e9155 100644 --- a/src/func/instances/composition.rs +++ b/src/func/instances/composition.rs @@ -14,25 +14,28 @@ use crate::func::class_prelude::*; pub struct CompositionInstance(U, V); impl<'a, U: WeakFunctor<'a>, V: WeakFunctor<'a>> WeakFunctor<'a> for CompositionInstance { - type F = U::F>; + type F = U::F>; } impl<'a, U: Functor<'a>, V: Functor<'a>> Functor<'a> for CompositionInstance { - fn fmap(fa: Self::F, f: impl 'a + FnOnce(A) -> B) -> Self::F { + fn fmap( + fa: Self::F, + f: impl 'a + Send + FnOnce(A) -> B, + ) -> Self::F { U::fmap(fa, |ua| V::fmap(ua, f)) } - fn replace(fa: Self::F, b: B) -> Self::F { + fn replace(fa: Self::F, b: B) -> Self::F { U::fmap(fa, |ua| V::replace(ua, b)) } - fn void(fa: Self::F) -> Self::F<()> { + fn void(fa: Self::F) -> Self::F<()> { U::fmap(fa, |ua| V::void(ua)) } } impl<'a, U: Pure<'a>, V: Pure<'a>> Pure<'a> for CompositionInstance { - fn pure(a: A) -> Self::F { + fn pure(a: A) -> Self::F { U::pure(V::pure(a)) } } @@ -41,7 +44,10 @@ impl<'a, U: Pure<'a>, V: Pure<'a>> Pure<'a> for CompositionInstance { impl<'a, U: ApplicativeLA2<'a>, V: ApplicativeSeq<'a>> ApplicativeSeq<'a> for CompositionInstance { - fn seq(ff: Self::F B>, fa: Self::F) -> Self::F { + fn seq( + ff: Self::F B>, + fa: Self::F, + ) -> Self::F { 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 { - fn la2( + fn la2( fa: Self::F, fb: Self::F, - f: impl 'a + FnOnce(A, B) -> C, + f: impl 'a + Send + FnOnce(A, B) -> C, ) -> Self::F { 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 { - fn tuple(fab: (Self::F, Self::F)) -> Self::F<(A, B)> { + fn tuple(fab: (Self::F, Self::F)) -> 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 { - fn select(fa: Self::F, fb: Self::F) -> SelectedWrapped<'a, A, B, Self> { + fn select( + fa: Self::F, + fb: Self::F, + ) -> 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 { - fn discard_first(fa: Self::F, fb: Self::F) -> Self::F { + fn discard_first(fa: Self::F, fb: Self::F) -> Self::F { U::la2(fa, fb, V::discard_first) } - fn discard_second(fa: Self::F, fb: Self::F) -> Self::F { + fn discard_second(fa: Self::F, fb: Self::F) -> Self::F { U::la2(fa, fb, V::discard_second) } } impl<'a, U: Monad<'a>, V: Monad<'a> + LocalFunctor<'a>> Monad<'a> for CompositionInstance { - fn bind(fa: Self::F, f: impl 'a + FnOnce(A) -> Self::F) -> Self::F { + fn bind( + fa: Self::F, + f: impl 'a + Send + FnOnce(A) -> Self::F, + ) -> Self::F { U::bind(fa, |ua| U::fmap(V::stuff::<_, U>(V::fmap(ua, f)), V::join)) } - fn iterate(f: impl Iterative<'a, T = Self, B = B>) -> Self::F { + fn iterate(f: impl Iterative<'a, T = Self, B = B>) -> Self::F { 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(ffa: Self::F>) -> Self::F { + fn join(ffa: Self::F>) -> Self::F { 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 { - fn fail(e: E) -> Self::F { + fn fail(e: E) -> Self::F { 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 { - fn unstuff(state: Self::F>) -> ControlFlow, A> { + fn unstuff( + state: Self::F>, + ) -> ControlFlow, A> { U::unstuff(U::fmap(state, V::unstuff)) } - fn stuff>(fa: Self::F>) -> T::F> { + fn stuff>(fa: Self::F>) -> T::F> { 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 { - type Shared = U::Shared>; + type Shared = U::Shared>; - fn share(fa: Self::F) -> Self::Shared { + fn share(fa: Self::F) -> Self::Shared { U::share(U::fmap(fa, V::share)) } - fn unshare(sa: Self::Shared) -> Self::F { + fn unshare(sa: Self::Shared) -> Self::F { U::fmap(U::unshare(sa), V::unshare) } } diff --git a/src/func/instances/effect.rs b/src/func/instances/effect.rs index 9b56e1d..c9c262b 100644 --- a/src/func/instances/effect.rs +++ b/src/func/instances/effect.rs @@ -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 WithEffect { } } -#[derive(SharedFunctorAny)] -pub struct EffectInstance(E); +pub struct EffectInstance(E); -impl WeakFunctorAny for EffectInstance { - type FAny<'a, A: 'a> = WithEffect +impl SharedFunctorAny for EffectInstance { + 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 WeakFunctorAny for EffectInstance { + type FAny<'a, A: 'a + Send> = WithEffect where Self: 'a; } -impl<'a, E: 'a> Functor<'a> for EffectInstance { - fn fmap(fa: Self::F, f: impl 'a + FnOnce(A) -> B) -> Self::F { +impl<'a, E: 'a + Send> Functor<'a> for EffectInstance { + fn fmap(fa: Self::F, f: impl 'a + FnOnce(A) -> B) -> Self::F { WithEffect { value: f(fa.value), effect: fa.effect, } } - fn replace(fa: Self::F, b: B) -> Self::F { + fn replace(fa: Self::F, b: B) -> Self::F { drop(fa.value); WithEffect { value: b, @@ -64,7 +83,7 @@ impl<'a, E: 'a> Functor<'a> for EffectInstance { } impl<'a, E: 'a + Effect> Pure<'a> for EffectInstance { - fn pure(a: A) -> Self::F { + fn pure(a: A) -> Self::F { WithEffect { value: a, effect: E::e_pure(), @@ -73,7 +92,10 @@ impl<'a, E: 'a + Effect> Pure<'a> for EffectInstance { } impl<'a, E: 'a + Effect> ApplicativeSeq<'a> for EffectInstance { - fn seq(ff: Self::F B>, fa: Self::F) -> Self::F { + fn seq( + ff: Self::F B>, + fa: Self::F, + ) -> Self::F { 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 { } impl<'a, E: 'a + Effect> ApplicativeLA2<'a> for EffectInstance { - fn la2( + fn la2( fa: Self::F, fb: Self::F, - f: impl 'a + FnOnce(A, B) -> C, + f: impl 'a + Send + FnOnce(A, B) -> C, ) -> Self::F { WithEffect { value: f(fa.value, fb.value), @@ -95,7 +117,7 @@ impl<'a, E: 'a + Effect> ApplicativeLA2<'a> for EffectInstance { } impl<'a, E: 'a + Effect> ApplicativeTuple<'a> for EffectInstance { - fn tuple((fa, fb): (Self::F, Self::F)) -> Self::F<(A, B)> { + fn tuple((fa, fb): (Self::F, Self::F)) -> 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 { impl<'a, E: 'a + Effect> ApplicativeSelect<'a> for EffectInstance {} impl<'a, E: 'a + Effect> Applicative<'a> for EffectInstance { - fn discard_first(fa: Self::F, fb: Self::F) -> Self::F { + fn discard_first(fa: Self::F, fb: Self::F) -> Self::F { drop(fa.value); WithEffect { value: fb.value, @@ -114,7 +136,7 @@ impl<'a, E: 'a + Effect> Applicative<'a> for EffectInstance { } } - fn discard_second(fa: Self::F, fb: Self::F) -> Self::F { + fn discard_second(fa: Self::F, fb: Self::F) -> Self::F { drop(fb.value); WithEffect { value: fa.value, @@ -124,11 +146,14 @@ impl<'a, E: 'a + Effect> Applicative<'a> for EffectInstance { } impl<'a, E: 'a + Effect> Monad<'a> for EffectInstance { - fn bind(fa: Self::F, f: impl 'a + FnOnce(A) -> Self::F) -> Self::F { + fn bind( + fa: Self::F, + f: impl 'a + FnOnce(A) -> Self::F, + ) -> Self::F { f(fa.value).e_after(fa.effect) } - fn iterate(mut f: impl Iterative<'a, T = Self, B = B>) -> Self::F { + fn iterate(mut f: impl Iterative<'a, T = Self, B = B>) -> Self::F { let mut effect = E::e_pure(); loop { let fa = f.next(); @@ -140,13 +165,13 @@ impl<'a, E: 'a + Effect> Monad<'a> for EffectInstance { } } - fn join(ffa: Self::F>) -> Self::F { + fn join(ffa: Self::F>) -> Self::F { ffa.value.e_after(ffa.effect) } } -impl<'a, E: 'a> LocalFunctor<'a> for EffectInstance { - fn stuff>(fa: Self::F>) -> T::F> { +impl<'a, E: 'a + Send> LocalFunctor<'a> for EffectInstance { + fn stuff>(fa: Self::F>) -> T::F> { T::fmap(fa.value, |a| WithEffect { value: a, effect: fa.effect, diff --git a/src/func/instances/future.rs b/src/func/instances/future.rs index 60bdb06..d0e5095 100644 --- a/src/func/instances/future.rs +++ b/src/func/instances/future.rs @@ -21,15 +21,18 @@ use crate::func::class_prelude::*; pub struct FutureInstance; impl WeakFunctorAny for FutureInstance { - type FAny<'a, A: 'a> = Pin>>; + type FAny<'a, A: 'a + Send> = Pin>>; } impl<'a> Functor<'a> for FutureInstance { - fn fmap(fa: Self::F, f: impl 'a + FnOnce(A) -> B) -> Self::F { + fn fmap( + fa: Self::F, + f: impl 'a + Send + FnOnce(A) -> B, + ) -> Self::F { Box::pin(async { f(fa.await) }) } - fn replace(fa: Self::F, b: B) -> Self::F { + fn replace(fa: Self::F, b: B) -> Self::F { 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) -> Self::F { + fn pure(a: A) -> Self::F { Box::pin(async { a }) } } impl<'a> ApplicativeSeq<'a> for FutureInstance { - fn seq(ff: Self::F B>, fa: Self::F) -> Self::F { + fn seq( + ff: Self::F B>, + fa: Self::F, + ) -> Self::F { 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( + fn la2( fa: Self::F, fb: Self::F, - f: impl 'a + FnOnce(A, B) -> C, + f: impl 'a + Send + FnOnce(A, B) -> C, ) -> Self::F { 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((fa, fb): (Self::F, Self::F)) -> Self::F<(A, B)> { + fn tuple((fa, fb): (Self::F, Self::F)) -> Self::F<(A, B)> { Box::pin(join(fa, fb)) } } impl<'a> ApplicativeSelect<'a> for FutureInstance { - fn select(fa: Self::F, fb: Self::F) -> SelectedWrapped<'a, A, B, Self> { + fn select( + fa: Self::F, + fb: Self::F, + ) -> 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(fa: Self::F, fb: Self::F) -> Self::F { + fn discard_first(fa: Self::F, fb: Self::F) -> Self::F { Box::pin(async { join!(fa, fb).1 }) } - fn discard_second(fa: Self::F, fb: Self::F) -> Self::F { + fn discard_second(fa: Self::F, fb: Self::F) -> Self::F { Box::pin(async { join!(fa, fb).0 }) } } impl<'a> Monad<'a> for FutureInstance { - fn bind(fa: Self::F, f: impl 'a + FnOnce(A) -> Self::F) -> Self::F { + fn bind( + fa: Self::F, + f: impl 'a + Send + FnOnce(A) -> Self::F, + ) -> Self::F { Box::pin(async { f(fa.await).await }) } - fn iterate(mut f: impl Iterative<'a, T = Self, B = B>) -> Self::F { + fn iterate(mut f: impl Iterative<'a, T = Self, B = B>) -> Self::F { Box::pin(async move { loop { match f.next().await { @@ -108,19 +120,19 @@ impl<'a> Monad<'a> for FutureInstance { }) } - fn join(ffa: Self::F>) -> Self::F { + fn join(ffa: Self::F>) -> Self::F { Box::pin(async { ffa.await.await }) } } impl<'a> SharedFunctor<'a> for FutureInstance { - type Shared = Shared>>>; + type Shared = Shared>>>; - fn share(fa: Self::F) -> Self::Shared { + fn share(fa: Self::F) -> Self::Shared { fa.shared() } - fn unshare(sa: Self::Shared) -> Self::F { + fn unshare(sa: Self::Shared) -> Self::F { Box::pin(sa) } } diff --git a/src/func/instances/lazy.rs b/src/func/instances/lazy.rs index c40d175..66c5aec 100644 --- a/src/func/instances/lazy.rs +++ b/src/func/instances/lazy.rs @@ -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 A>; + type FAny<'a, A: 'a + Send> = Box A>; } impl<'a> Functor<'a> for LazyInstance { - fn fmap(fa: Self::F, f: impl 'a + FnOnce(A) -> B) -> Self::F { + fn fmap( + fa: Self::F, + f: impl 'a + Send + FnOnce(A) -> B, + ) -> Self::F { Box::new(|| f(fa())) } - fn replace(fa: Self::F, b: B) -> Self::F { + fn replace(fa: Self::F, b: B) -> Self::F { drop(fa); Box::new(|| b) } - fn void(fa: Self::F) -> Self::F<()> { + fn void(fa: Self::F) -> Self::F<()> { drop(fa); Box::new(|| ()) } } impl<'a> Pure<'a> for LazyInstance { - fn pure(a: A) -> Self::F { + fn pure(a: A) -> Self::F { Box::new(|| a) } } impl<'a> ApplicativeSeq<'a> for LazyInstance { - fn seq(ff: Self::F B>, fa: Self::F) -> Self::F { + fn seq( + ff: Self::F B>, + fa: Self::F, + ) -> Self::F { Box::new(|| ff()(fa())) } } impl<'a> ApplicativeLA2<'a> for LazyInstance { - fn la2( + fn la2( fa: Self::F, fb: Self::F, - f: impl 'a + FnOnce(A, B) -> C, + f: impl 'a + Send + FnOnce(A, B) -> C, ) -> Self::F { Box::new(|| f(fa(), fb())) } } impl<'a> ApplicativeTuple<'a> for LazyInstance { - fn tuple((fa, fb): (Self::F, Self::F)) -> Self::F<(A, B)> { + fn tuple((fa, fb): (Self::F, Self::F)) -> 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(fa: Self::F, fb: Self::F) -> Self::F { + fn discard_first(fa: Self::F, fb: Self::F) -> Self::F { drop(fa); fb } - fn discard_second(fa: Self::F, fb: Self::F) -> Self::F { + fn discard_second(fa: Self::F, fb: Self::F) -> Self::F { drop(fb); fa } } impl<'a> Monad<'a> for LazyInstance { - fn bind(fa: Self::F, f: impl 'a + FnOnce(A) -> Self::F) -> Self::F { + fn bind( + fa: Self::F, + f: impl 'a + Send + FnOnce(A) -> Self::F, + ) -> Self::F { Box::new(|| f(fa())()) } - fn iterate(mut f: impl Iterative<'a, T = Self, B = B>) -> Self::F { + fn iterate(mut f: impl Iterative<'a, T = Self, B = B>) -> Self::F { loop { match f.next()() { ControlFlow::Continue(next_f) => f = next_f, @@ -91,28 +98,7 @@ impl<'a> Monad<'a> for LazyInstance { } } - fn join(ffa: Self::F>) -> Self::F { + fn join(ffa: Self::F>) -> Self::F { Box::new(|| ffa()()) } } - -fn unshare<'a, A: 'a + Clone>(shared: &mut Option 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 = Rc A>>>>; - - fn share(fa: Self::F) -> Self::Shared { - Rc::new(RefCell::new(Some(fa))) - } - - fn unshare(sa: Self::Shared) -> Self::F { - Box::new(move || unshare(&mut *sa.borrow_mut())) - } -} diff --git a/src/func/instances/option.rs b/src/func/instances/option.rs index c174025..b87a1a5 100644 --- a/src/func/instances/option.rs +++ b/src/func/instances/option.rs @@ -17,49 +17,55 @@ use crate::func::class_prelude::*; pub struct OptionInstance; impl WeakFunctorAny for OptionInstance { - type FAny<'a, A: 'a> = Option; + type FAny<'a, A: 'a + Send> = Option; } impl<'a> Functor<'a> for OptionInstance { - fn fmap(fa: Self::F, f: impl 'a + FnOnce(A) -> B) -> Self::F { + fn fmap( + fa: Self::F, + f: impl 'a + Send + FnOnce(A) -> B, + ) -> Self::F { fa.map(f) } - fn replace(fa: Self::F, b: B) -> Self::F { + fn replace(fa: Self::F, b: B) -> Self::F { fa?; Self::pure(b) } - fn void(fa: Self::F) -> Self::F<()> { + fn void(fa: Self::F) -> Self::F<()> { fa?; Self::pure(()) } } impl<'a> Pure<'a> for OptionInstance { - fn pure(a: A) -> Self::F { + fn pure(a: A) -> Self::F { Some(a) } } impl<'a> ApplicativeSeq<'a> for OptionInstance { - fn seq(ff: Self::F B>, fa: Self::F) -> Self::F { + fn seq( + ff: Self::F B>, + fa: Self::F, + ) -> Self::F { Self::pure(ff?(fa?)) } } impl<'a> ApplicativeLA2<'a> for OptionInstance { - fn la2( + fn la2( fa: Self::F, fb: Self::F, - f: impl 'a + FnOnce(A, B) -> C, + f: impl 'a + Send + FnOnce(A, B) -> C, ) -> Self::F { Self::pure(f(fa?, fb?)) } } impl<'a> ApplicativeTuple<'a> for OptionInstance { - fn tuple((fa, fb): (Self::F, Self::F)) -> Self::F<(A, B)> { + fn tuple((fa, fb): (Self::F, Self::F)) -> 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(fa: Self::F, fb: Self::F) -> Self::F { + fn discard_first(fa: Self::F, fb: Self::F) -> Self::F { fa?; fb } - fn discard_second(fa: Self::F, fb: Self::F) -> Self::F { + fn discard_second(fa: Self::F, fb: Self::F) -> Self::F { fb?; fa } } impl<'a> Monad<'a> for OptionInstance { - fn bind(fa: Self::F, f: impl 'a + FnOnce(A) -> Self::F) -> Self::F { + fn bind( + fa: Self::F, + f: impl 'a + FnOnce(A) -> Self::F, + ) -> Self::F { f(fa?) } - fn iterate(mut f: impl Iterative<'a, T = Self, B = B>) -> Self::F { + fn iterate(mut f: impl Iterative<'a, T = Self, B = B>) -> Self::F { loop { match f.next()? { ControlFlow::Continue(next_f) => f = next_f, @@ -92,13 +101,15 @@ impl<'a> Monad<'a> for OptionInstance { } } - fn join(ffa: Self::F>) -> Self::F { + fn join(ffa: Self::F>) -> Self::F { ffa? } } impl<'a> LocalFunctor<'a> for OptionInstance { - fn unstuff(state: Self::F>) -> ControlFlow, A> { + fn unstuff( + state: Self::F>, + ) -> ControlFlow, 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>(fa: Self::F>) -> T::F> { + fn stuff>(fa: Self::F>) -> T::F> { 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(_e: ()) -> Self::F { + fn fail(_e: ()) -> Self::F { None } } @@ -127,7 +138,7 @@ mod option_tests { use super::OptionInstance as T; impl<'a> tests::Eqr<'a> for T { - fn eqr( + fn eqr( name: &'a str, left: Self::F, right: Self::F, @@ -137,7 +148,7 @@ mod option_tests { } impl<'a> test_suite::FunctorTestSuite<'a> for T { - fn sample Self::F)>(mut f: F) { + fn sample Self::F))>(mut f: F) { f(&|_| None); f(&|a| Some(a)); } diff --git a/src/func/instances/overload.rs b/src/func/instances/overload.rs index 1d100a6..981755c 100644 --- a/src/func/instances/overload.rs +++ b/src/func/instances/overload.rs @@ -12,34 +12,37 @@ use crate::func::class_prelude::*; pub struct OverloadInstance(T, O); -pub trait DeriveWeakFunctor {} +pub trait DeriveWeakFunctor: Send {} impl DeriveWeakFunctor for O {} -pub trait DeriveFunctor {} +pub trait DeriveFunctor: Send {} impl DeriveFunctor for O {} -pub trait DeriveApplicative {} +pub trait DeriveApplicative: Send {} impl DeriveApplicative for O {} -pub trait DeriveMonad {} +pub trait DeriveMonad: Send {} impl<'a, T: WeakFunctor<'a>, O: 'a + DeriveWeakFunctor> WeakFunctor<'a> for OverloadInstance { - type F = T::F; + type F = T::F; } impl<'a, T: Functor<'a>, O: 'a + DeriveFunctor> Functor<'a> for OverloadInstance { - fn fmap(fa: Self::F, f: impl 'a + FnOnce(A) -> B) -> Self::F { + fn fmap( + fa: Self::F, + f: impl 'a + Send + FnOnce(A) -> B, + ) -> Self::F { T::fmap(fa, f) } - fn replace(fa: Self::F, b: B) -> Self::F { + fn replace(fa: Self::F, b: B) -> Self::F { T::replace(fa, b) } - fn void(fa: Self::F) -> Self::F<()> { + fn void(fa: Self::F) -> Self::F<()> { T::void(fa) } } impl<'a, T: Pure<'a>, O: 'a + DeriveApplicative> Pure<'a> for OverloadInstance { - fn pure(a: A) -> Self::F { + fn pure(a: A) -> Self::F { T::pure(a) } } @@ -47,7 +50,10 @@ impl<'a, T: Pure<'a>, O: 'a + DeriveApplicative> Pure<'a> for OverloadInstance, O: 'a + DeriveApplicative> ApplicativeSeq<'a> for OverloadInstance { - fn seq(ff: Self::F B>, fa: Self::F) -> Self::F { + fn seq( + ff: Self::F B>, + fa: Self::F, + ) -> Self::F { 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 { - fn la2( + fn la2( fa: Self::F, fb: Self::F, - f: impl 'a + FnOnce(A, B) -> C, + f: impl 'a + Send + FnOnce(A, B) -> C, ) -> Self::F { 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 { - fn tuple(fab: (Self::F, Self::F)) -> Self::F<(A, B)> { + fn tuple(fab: (Self::F, Self::F)) -> 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 { - fn select(fa: Self::F, fb: Self::F) -> SelectedWrapped<'a, A, B, Self> { + fn select( + fa: Self::F, + fb: Self::F, + ) -> 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 { - fn discard_first(fa: Self::F, fb: Self::F) -> Self::F { + fn discard_first(fa: Self::F, fb: Self::F) -> Self::F { T::discard_first(fa, fb) } - fn discard_second(fa: Self::F, fb: Self::F) -> Self::F { + fn discard_second(fa: Self::F, fb: Self::F) -> Self::F { 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 { - fn bind(fa: Self::F, f: impl 'a + FnOnce(A) -> Self::F) -> Self::F { + fn bind( + fa: Self::F, + f: impl 'a + Send + FnOnce(A) -> Self::F, + ) -> Self::F { T::bind(fa, f) } - fn iterate(f: impl Iterative<'a, T = Self, B = B>) -> Self::F { + fn iterate(f: impl Iterative<'a, T = Self, B = B>) -> Self::F { T::iterate(OverloadIterative::new(f)) } - fn join(ffa: Self::F>) -> Self::F { + fn join(ffa: Self::F>) -> Self::F { T::join(ffa) } } pub struct DeriveFail(Ex); -impl DeriveMonad for DeriveFail {} +impl DeriveMonad for DeriveFail {} -impl<'a, E: 'a, Ex: 'a, T: MonadFail<'a, Result>> Fail<'a, E> for EmbedFail { - fn fail(e: E) -> Self::F { +impl<'a, E: 'a + Send, Ex: 'a + Send, T: MonadFail<'a, Result>> Fail<'a, E> + for EmbedFail +{ + fn fail(e: E) -> Self::F { T::fail(Ok(e)) } } @@ -142,19 +156,25 @@ impl<'a, E: 'a, Ex: 'a, T: MonadFail<'a, Result>> Fail<'a, E> for EmbedFa /// Instance of [`MonadFailAny`] for [`EmbedFail`]. pub struct DeriveFailAny(Ex, Fallible); -impl<'a, Ex: 'a, Fallible: MonadFailAny<'a>> MonadFailAny<'a> for DeriveFailAny { - type W = EmbedFail>, Ex>; +impl<'a, Ex: 'a + Send, Fallible: MonadFailAny<'a>> MonadFailAny<'a> + for DeriveFailAny +{ + type W = EmbedFail>, Ex>; type T = Fallible::W; - fn unstuff(wa: WrapE<'a, A, E, Self>) -> Wrap<'a, Result, Self::T> { + fn unstuff( + wa: WrapE<'a, A, E, Self>, + ) -> Wrap<'a, Result, Self::T> { Fallible::bind_err( as Functor>::fmap(wa, Ok), |err| match err { Ok(e) => Fallible::pure(Err(e)), Err(ex) => Fallible::fail(ex), }) } - fn stuff(fa: Wrap<'a, Result, Self::T>) -> WrapE<'a, A, E, Self> { + fn stuff( + fa: Wrap<'a, Result, 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( + fn map_err( 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( + fn bind_err( 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( + fn bind( wa: WrapE<'a, A, E0, Self>, - f: impl 'a + FnOnce(Result) -> WrapE<'a, B, E1, Self>, + f: impl 'a + Send + FnOnce(Result) -> 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 { - type Shared = T::Shared; + type Shared = T::Shared; - fn share(fa: Self::F) -> Self::Shared { + fn share(fa: Self::F) -> Self::Shared { T::share(fa) } - fn unshare(sa: Self::Shared) -> Self::F { + fn unshare(sa: Self::Shared) -> Self::F { T::unshare(sa) } } diff --git a/src/func/instances/result.rs b/src/func/instances/result.rs index 3eb8ddd..b1b26dd 100644 --- a/src/func/instances/result.rs +++ b/src/func/instances/result.rs @@ -14,77 +14,105 @@ use crate::func::class_prelude::*; -#[derive(SharedFunctorAny)] -pub struct ResultInstance(E); +pub struct ResultInstance(E); -impl WeakFunctorAny for ResultInstance { - type FAny<'a, A: 'a> = Result where Self: 'a; +impl SharedFunctorAny for ResultInstance { + 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<'a, E: 'a> Functor<'a> for ResultInstance { - fn fmap(fa: Self::F, f: impl 'a + FnOnce(A) -> B) -> Self::F { +impl WeakFunctorAny for ResultInstance { + type FAny<'a, A: 'a + Send> = Result where Self: 'a; +} + +impl<'a, E: 'a + Send> Functor<'a> for ResultInstance { + fn fmap( + fa: Self::F, + f: impl 'a + Send + FnOnce(A) -> B, + ) -> Self::F { fa.map(f) } - fn replace(fa: Self::F, b: B) -> Self::F { + fn replace(fa: Self::F, b: B) -> Self::F { fa?; Self::pure(b) } - fn void(fa: Self::F) -> Self::F<()> { + fn void(fa: Self::F) -> Self::F<()> { fa?; Self::pure(()) } } -impl<'a, E: 'a> Pure<'a> for ResultInstance { - fn pure(a: A) -> Self::F { +impl<'a, E: 'a + Send> Pure<'a> for ResultInstance { + fn pure(a: A) -> Self::F { Ok(a) } } -impl<'a, E: 'a> ApplicativeSeq<'a> for ResultInstance { - fn seq(ff: Self::F B>, fa: Self::F) -> Self::F { +impl<'a, E: 'a + Send> ApplicativeSeq<'a> for ResultInstance { + fn seq( + ff: Self::F B>, + fa: Self::F, + ) -> Self::F { Self::pure(ff?(fa?)) } } -impl<'a, E: 'a> ApplicativeLA2<'a> for ResultInstance { - fn la2( +impl<'a, E: 'a + Send> ApplicativeLA2<'a> for ResultInstance { + fn la2( fa: Self::F, fb: Self::F, - f: impl 'a + FnOnce(A, B) -> C, + f: impl 'a + Send + FnOnce(A, B) -> C, ) -> Self::F { Self::pure(f(fa?, fb?)) } } -impl<'a, E: 'a> ApplicativeTuple<'a> for ResultInstance { - fn tuple((fa, fb): (Self::F, Self::F)) -> Self::F<(A, B)> { +impl<'a, E: 'a + Send> ApplicativeTuple<'a> for ResultInstance { + fn tuple((fa, fb): (Self::F, Self::F)) -> Self::F<(A, B)> { Self::pure((fa?, fb?)) } } -impl<'a, E: 'a> ApplicativeSelect<'a> for ResultInstance {} +impl<'a, E: 'a + Send> ApplicativeSelect<'a> for ResultInstance {} -impl<'a, E: 'a> Applicative<'a> for ResultInstance { - fn discard_first(fa: Self::F, fb: Self::F) -> Self::F { +impl<'a, E: 'a + Send> Applicative<'a> for ResultInstance { + fn discard_first(fa: Self::F, fb: Self::F) -> Self::F { fa?; fb } - fn discard_second(fa: Self::F, fb: Self::F) -> Self::F { + fn discard_second(fa: Self::F, fb: Self::F) -> Self::F { fb?; fa } } -impl<'a, E: 'a> Monad<'a> for ResultInstance { - fn bind(fa: Self::F, f: impl 'a + FnOnce(A) -> Self::F) -> Self::F { +impl<'a, E: 'a + Send> Monad<'a> for ResultInstance { + fn bind( + fa: Self::F, + f: impl 'a + FnOnce(A) -> Self::F, + ) -> Self::F { f(fa?) } - fn iterate(mut f: impl Iterative<'a, T = Self, B = B>) -> Self::F { + fn iterate(mut f: impl Iterative<'a, T = Self, B = B>) -> Self::F { loop { match f.next()? { ControlFlow::Continue(next_f) => f = next_f, @@ -93,13 +121,15 @@ impl<'a, E: 'a> Monad<'a> for ResultInstance { } } - fn join(ffa: Self::F>) -> Self::F { + fn join(ffa: Self::F>) -> Self::F { ffa? } } -impl<'a, E: 'a> LocalFunctor<'a> for ResultInstance { - fn unstuff(state: Self::F>) -> ControlFlow, A> { +impl<'a, E: 'a + Send> LocalFunctor<'a> for ResultInstance { + fn unstuff( + state: Self::F>, + ) -> ControlFlow, 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 { } } - fn stuff>(fa: Self::F>) -> T::F> { + fn stuff>(fa: Self::F>) -> T::F> { 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 { } } -impl<'a, E: 'a> Fail<'a, E> for ResultInstance { - fn fail(e: E) -> Self::F { +impl<'a, E: 'a + Send> Fail<'a, E> for ResultInstance { + fn fail(e: E) -> Self::F { Err(e) } } pub struct ResultFailAny; -trait ResultExt<'a, A: 'a, E0: 'a>: 'a { - fn bind_err(self, f: impl 'a + FnOnce(E0) -> Result) -> Result; +trait ResultExt<'a, A: 'a + Send, E0: 'a + Send>: 'a { + fn bind_err(self, f: impl 'a + FnOnce(E0) -> Result) -> Result; } -impl<'a, A: 'a, E0: 'a> ResultExt<'a, A, E0> for Result { - fn bind_err(self, f: impl 'a + FnOnce(E0) -> Result) -> Result { +impl<'a, A: 'a + Send, E0: 'a + Send> ResultExt<'a, A, E0> for Result { + fn bind_err(self, f: impl 'a + FnOnce(E0) -> Result) -> Result { 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 { } impl<'a> MonadFailAny<'a> for ResultFailAny { - type W = ResultInstance; + type W = ResultInstance; type T = instances::solo::SoloInstance; - fn unstuff(wa: WrapE<'a, A, E, Self>) -> Wrap<'a, Result, Self::T> { + fn unstuff( + wa: WrapE<'a, A, E, Self>, + ) -> Wrap<'a, Result, Self::T> { wa } - fn stuff(fa: Wrap<'a, Result, Self::T>) -> WrapE<'a, A, E, Self> { + fn stuff( + fa: Wrap<'a, Result, Self::T>, + ) -> WrapE<'a, A, E, Self> { fa } - fn map_err( + fn map_err( wa: WrapE<'a, A, E0, Self>, f: impl 'a + FnOnce(E0) -> E1, ) -> WrapE<'a, A, E1, Self> { wa.map_err(f) } - fn bind_err( + fn bind_err( 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( + fn bind( wa: WrapE<'a, A, E0, Self>, f: impl 'a + FnOnce(Result) -> WrapE<'a, B, E1, Self>, ) -> WrapE<'a, B, E1, Self> { f(wa) } - fn rotate_out( + fn rotate_out( wa: WrapE<'a, Result, E0, Self>, ) -> WrapE<'a, A, Result, Self> { match wa { @@ -184,28 +218,32 @@ impl<'a> MonadFailAny<'a> for ResultFailAny { pub struct ResultFailOver(T); impl<'a, T: Monad<'a>> MonadFailAny<'a> for ResultFailOver { - type W = super::composition::CompositionInstance>; + type W = super::composition::CompositionInstance>; type T = T; - fn unstuff(wa: WrapE<'a, A, E, Self>) -> Wrap<'a, Result, Self::T> { + fn unstuff( + wa: WrapE<'a, A, E, Self>, + ) -> Wrap<'a, Result, Self::T> { wa } - fn stuff(fa: Wrap<'a, Result, Self::T>) -> WrapE<'a, A, E, Self> { + fn stuff( + fa: Wrap<'a, Result, Self::T>, + ) -> WrapE<'a, A, E, Self> { fa } - fn map_err( + fn map_err( 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( + fn bind_err( 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 { }) } - fn bind( + fn bind( wa: WrapE<'a, A, E0, Self>, - f: impl 'a + FnOnce(Result) -> WrapE<'a, B, E1, Self>, + f: impl 'a + Send + FnOnce(Result) -> WrapE<'a, B, E1, Self>, ) -> WrapE<'a, B, E1, Self> { T::bind(wa, f) } - fn rotate_out( + fn rotate_out( wa: WrapE<'a, Result, E0, Self>, ) -> WrapE<'a, A, Result, Self> { T::fmap(wa, ::rotate_out) diff --git a/src/func/instances/solo.rs b/src/func/instances/solo.rs index 9a17934..4453f89 100644 --- a/src/func/instances/solo.rs +++ b/src/func/instances/solo.rs @@ -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(fa: Self::F, f: impl 'a + FnOnce(A) -> B) -> Self::F { + fn fmap(fa: Self::F, f: impl 'a + FnOnce(A) -> B) -> Self::F { f(fa) } - fn replace(fa: Self::F, b: B) -> Self::F { + fn replace(fa: Self::F, b: B) -> Self::F { drop(fa); b } - fn void(fa: Self::F) -> Self::F<()> { + fn void(fa: Self::F) -> Self::F<()> { drop(fa); } } impl<'a> Pure<'a> for SoloInstance { - fn pure(a: A) -> Self::F { + fn pure(a: A) -> Self::F { a } } impl<'a> ApplicativeSeq<'a> for SoloInstance { - fn seq(ff: Self::F B>, fa: Self::F) -> Self::F { + fn seq( + ff: Self::F B>, + fa: Self::F, + ) -> Self::F { ff(fa) } } impl<'a> ApplicativeLA2<'a> for SoloInstance { - fn la2( + fn la2( fa: Self::F, fb: Self::F, - f: impl 'a + FnOnce(A, B) -> C, + f: impl 'a + Send + FnOnce(A, B) -> C, ) -> Self::F { f(fa, fb) } } impl<'a> ApplicativeTuple<'a> for SoloInstance { - fn tuple((fa, fb): (Self::F, Self::F)) -> Self::F<(A, B)> { + fn tuple((fa, fb): (Self::F, Self::F)) -> 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(fa: Self::F, fb: Self::F) -> Self::F { + fn discard_first(fa: Self::F, fb: Self::F) -> Self::F { drop(fa); fb } - fn discard_second(fa: Self::F, fb: Self::F) -> Self::F { + fn discard_second(fa: Self::F, fb: Self::F) -> Self::F { drop(fb); fa } } impl<'a> Monad<'a> for SoloInstance { - fn bind(fa: Self::F, f: impl 'a + FnOnce(A) -> Self::F) -> Self::F { + fn bind( + fa: Self::F, + f: impl 'a + FnOnce(A) -> Self::F, + ) -> Self::F { f(fa) } - fn iterate(mut f: impl Iterative<'a, T = Self, B = B>) -> Self::F { + fn iterate(mut f: impl Iterative<'a, T = Self, B = B>) -> Self::F { loop { match f.next() { ControlFlow::Continue(next_f) => f = next_f, @@ -88,23 +94,25 @@ impl<'a> Monad<'a> for SoloInstance { } } - fn join(ffa: Self::F>) -> Self::F { + fn join(ffa: Self::F>) -> Self::F { ffa } } impl<'a> LocalFunctor<'a> for SoloInstance { - fn unstuff(state: Self::F>) -> ControlFlow, A> { + fn unstuff( + state: Self::F>, + ) -> ControlFlow, A> { state } - fn stuff>(fa: Self::F>) -> T::F> { + fn stuff>(fa: Self::F>) -> T::F> { fa } } impl<'a> Fail<'a, std::convert::Infallible> for SoloInstance { - fn fail(e: std::convert::Infallible) -> Self::F { + fn fail(e: std::convert::Infallible) -> Self::F { match e {} } } diff --git a/src/func/instances/stackless.rs b/src/func/instances/stackless.rs index 7f8a57b..76fb4a7 100644 --- a/src/func/instances/stackless.rs +++ b/src/func/instances/stackless.rs @@ -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 { +trait IntoOet: Send { fn into_oet<'t>(self: Box, f: Box) -> Oet<'t> where Self: 't, A: 't; } -impl<'a, A: 'a, B: 'a, F: 'a + FnOnce(A) -> Stackless<'a, B>> IntoOet +impl<'a, A: 'a + Send, B: 'a + Send, F: 'a + Send + FnOnce(A) -> Stackless<'a, B>> IntoOet for Wrapper<(&'a (), B), (Stackless<'a, A>, F)> { fn into_oet<'t>(self: Box, f: Box) -> Oet<'t> @@ -98,7 +98,7 @@ impl<'a, A: 'a, B: 'a, F: 'a + FnOnce(A) -> Stackless<'a, B>> IntoOet 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 } } -impl<'a, A: 'a, B: 'a, F: 'a + FnOnce(A) -> B> IntoOet +impl<'a, A: 'a + Send, B: 'a + Send, F: 'a + Send + FnOnce(A) -> B> IntoOet for Wrapper<(&'a (), B, ()), (Stackless<'a, A>, F)> { fn into_oet<'t>(self: Box, f: Box) -> Oet<'t> @@ -119,7 +119,7 @@ impl<'a, A: 'a, B: 'a, F: 'a + FnOnce(A) -> B> IntoOet 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 } } -impl IntoOet for Wrapper<(), A> { +impl IntoOet for Wrapper<(), A> { fn into_oet<'t>(self: Box, f: Box) -> Oet<'t> where Self: 't, @@ -152,39 +152,42 @@ type StackessDyn<'a, A> = dyn 'a + IntoOet; pub struct Stackless<'a, A: 'a>(Box>); -fn set_cell(cell: Rc>>, a: A) { +fn set_cell(cell: Arc>>, a: A) { if cell.replace(Some(a)).is_some() { panic!("MITM overwritten") } } -fn get_cell(cell: Rc>>) -> A { +fn get_cell(cell: Arc>>) -> 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`] and `FnOnce(A) -> Stackless` into [`Stackless`]. - pub fn bind(self, f: impl 'a + FnOnce(A) -> Stackless<'a, B>) -> Stackless<'a, B> { + pub fn bind( + 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(self, f: impl 'a + FnOnce(A) -> B) -> Stackless<'a, B> { + pub fn map(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 for Stackless<'a, A> { +impl<'a, A: 'a + Send> From for Stackless<'a, A> { fn from(value: A) -> Self { Stackless(Box::new(Wrapper(value, PhantomData))) } @@ -203,39 +206,45 @@ impl<'a, A: 'a> From 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(fa: Self::F, f: impl 'a + FnOnce(A) -> B) -> Self::F { + fn fmap( + fa: Self::F, + f: impl 'a + Send + FnOnce(A) -> B, + ) -> Self::F { fa.map(f) } } impl<'a> Pure<'a> for StacklessInstance { - fn pure(a: A) -> Self::F { + fn pure(a: A) -> Self::F { Stackless::from(a) } } impl<'a> ApplicativeSeq<'a> for StacklessInstance { - fn seq(ff: Self::F B>, fa: Self::F) -> Self::F { + fn seq( + ff: Self::F B>, + fa: Self::F, + ) -> Self::F { ff.bind(|f| fa.map(f)) } } impl<'a> ApplicativeLA2<'a> for StacklessInstance { - fn la2( + fn la2( fa: Self::F, fb: Self::F, - f: impl 'a + FnOnce(A, B) -> C, + f: impl 'a + Send + FnOnce(A, B) -> C, ) -> Self::F { Self::_la2_via_seq(f, fa, fb) } } impl<'a> ApplicativeTuple<'a> for StacklessInstance { - fn tuple((fa, fb): (Self::F, Self::F)) -> Self::F<(A, B)> { + fn tuple((fa, fb): (Self::F, Self::F)) -> 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(fa: Self::F, f: impl 'a + FnOnce(A) -> Self::F) -> Self::F { + fn bind( + fa: Self::F, + f: impl 'a + Send + FnOnce(A) -> Self::F, + ) -> Self::F { fa.bind(f) } - fn iterate(f: impl Iterative<'a, T = Self, B = B>) -> Self::F { + fn iterate(f: impl Iterative<'a, T = Self, B = B>) -> Self::F { 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( + fn eqr( name: &'a str, left: Self::F, right: Self::F, @@ -276,7 +288,7 @@ mod stackless_test { } impl<'a> test_suite::FunctorTestSuite<'a> for T { - fn sample Self::F)>(mut f: F) { + fn sample Self::F))>(mut f: F) { f(&|a| a.into()); } } diff --git a/src/func/instances/tryfuture.rs b/src/func/instances/tryfuture.rs index bd35f32..6b93311 100644 --- a/src/func/instances/tryfuture.rs +++ b/src/func/instances/tryfuture.rs @@ -19,16 +19,19 @@ use crate::func::class_prelude::*; pub struct TryFutureInstance(E); -impl WeakFunctorAny for TryFutureInstance { - type FAny<'a, A: 'a> = Pin>>> where Self: 'a; +impl WeakFunctorAny for TryFutureInstance { + type FAny<'a, A: 'a + Send> = Pin>>> where Self: 'a; } -impl<'a, E: 'a> Functor<'a> for TryFutureInstance { - fn fmap(fa: Self::F, f: impl 'a + FnOnce(A) -> B) -> Self::F { +impl<'a, E: 'a + Send> Functor<'a> for TryFutureInstance { + fn fmap( + fa: Self::F, + f: impl 'a + Send + FnOnce(A) -> B, + ) -> Self::F { Box::pin(async { Ok(f(fa.await?)) }) } - fn replace(fa: Self::F, b: B) -> Self::F { + fn replace(fa: Self::F, b: B) -> Self::F { Box::pin(async { fa.await?; Ok(b) @@ -36,14 +39,17 @@ impl<'a, E: 'a> Functor<'a> for TryFutureInstance { } } -impl<'a, E: 'a> Pure<'a> for TryFutureInstance { - fn pure(a: A) -> Self::F { +impl<'a, E: 'a + Send> Pure<'a> for TryFutureInstance { + fn pure(a: A) -> Self::F { Box::pin(async { Ok(a) }) } } -impl<'a, E: 'a> ApplicativeSeq<'a> for TryFutureInstance { - fn seq(ff: Self::F B>, fa: Self::F) -> Self::F { +impl<'a, E: 'a + Send> ApplicativeSeq<'a> for TryFutureInstance { + fn seq( + ff: Self::F B>, + fa: Self::F, + ) -> Self::F { 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 { } } -impl<'a, E: 'a> ApplicativeLA2<'a> for TryFutureInstance { - fn la2( +impl<'a, E: 'a + Send> ApplicativeLA2<'a> for TryFutureInstance { + fn la2( fa: Self::F, fb: Self::F, - f: impl 'a + FnOnce(A, B) -> C, + f: impl 'a + Send + FnOnce(A, B) -> C, ) -> Self::F { Box::pin(async { let (a, b) = try_join!(fa, fb)?; @@ -64,14 +70,17 @@ impl<'a, E: 'a> ApplicativeLA2<'a> for TryFutureInstance { } } -impl<'a, E: 'a> ApplicativeTuple<'a> for TryFutureInstance { - fn tuple((fa, fb): (Self::F, Self::F)) -> Self::F<(A, B)> { +impl<'a, E: 'a + Send> ApplicativeTuple<'a> for TryFutureInstance { + fn tuple((fa, fb): (Self::F, Self::F)) -> Self::F<(A, B)> { Box::pin(async { try_join!(fa, fb) }) } } -impl<'a, E: 'a> ApplicativeSelect<'a> for TryFutureInstance { - fn select(fa: Self::F, fb: Self::F) -> SelectedWrapped<'a, A, B, Self> { +impl<'a, E: 'a + Send> ApplicativeSelect<'a> for TryFutureInstance { + fn select( + fa: Self::F, + fb: Self::F, + ) -> 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 { } } -impl<'a, E: 'a> Applicative<'a> for TryFutureInstance { - fn discard_first(fa: Self::F, fb: Self::F) -> Self::F { +impl<'a, E: 'a + Send> Applicative<'a> for TryFutureInstance { + fn discard_first(fa: Self::F, fb: Self::F) -> Self::F { Box::pin(async { Ok(try_join!(fa, fb)?.1) }) } - fn discard_second(fa: Self::F, fb: Self::F) -> Self::F { + fn discard_second(fa: Self::F, fb: Self::F) -> Self::F { Box::pin(async { Ok(try_join!(fa, fb)?.0) }) } } -impl<'a, E: 'a> Monad<'a> for TryFutureInstance { - fn bind(fa: Self::F, f: impl 'a + FnOnce(A) -> Self::F) -> Self::F { +impl<'a, E: 'a + Send> Monad<'a> for TryFutureInstance { + fn bind( + fa: Self::F, + f: impl 'a + Send + FnOnce(A) -> Self::F, + ) -> Self::F { Box::pin(async { f(fa.await?).await }) } - fn iterate(mut f: impl Iterative<'a, T = Self, B = B>) -> Self::F { + fn iterate(mut f: impl Iterative<'a, T = Self, B = B>) -> Self::F { Box::pin(async move { loop { match f.next().await? { @@ -109,25 +121,26 @@ impl<'a, E: 'a> Monad<'a> for TryFutureInstance { }) } - fn join(ffa: Self::F>) -> Self::F { + fn join(ffa: Self::F>) -> Self::F { Box::pin(async { ffa.await?.await }) } } -impl<'a, E: 'a + Clone> SharedFunctor<'a> for TryFutureInstance { - type Shared = Shared>>>>; +impl<'a, E: 'a + Send + Sync + Clone> SharedFunctor<'a> for TryFutureInstance { + type Shared = + Shared>>>>; - fn share(fa: Self::F) -> Self::Shared { + fn share(fa: Self::F) -> Self::Shared { fa.shared() } - fn unshare(sa: Self::Shared) -> Self::F { + fn unshare(sa: Self::Shared) -> Self::F { Box::pin(sa) } } -impl<'a, E: 'a> Fail<'a, E> for TryFutureInstance { - fn fail(e: E) -> Self::F { +impl<'a, E: 'a + Send> Fail<'a, E> for TryFutureInstance { + fn fail(e: E) -> Self::F { Box::pin(async { Err(e) }) } } @@ -135,28 +148,32 @@ impl<'a, E: 'a> Fail<'a, E> for TryFutureInstance { pub struct FutureFailAny; impl<'a> MonadFailAny<'a> for FutureFailAny { - type W = TryFutureInstance; + type W = TryFutureInstance; type T = instances::future::FutureInstance; - fn unstuff(wa: WrapE<'a, A, E, Self>) -> Wrap<'a, Result, Self::T> { + fn unstuff( + wa: WrapE<'a, A, E, Self>, + ) -> Wrap<'a, Result, Self::T> { wa } - fn stuff(fa: Wrap<'a, Result, Self::T>) -> WrapE<'a, A, E, Self> { + fn stuff( + fa: Wrap<'a, Result, Self::T>, + ) -> WrapE<'a, A, E, Self> { fa } - fn map_err( + fn map_err( 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( + fn bind_err( 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( + fn bind( wa: WrapE<'a, A, E0, Self>, - f: impl 'a + FnOnce(Result) -> WrapE<'a, B, E1, Self>, + f: impl 'a + Send + FnOnce(Result) -> WrapE<'a, B, E1, Self>, ) -> WrapE<'a, B, E1, Self> { Box::pin(async { f(wa.await).await }) } - fn rotate_out( + fn rotate_out( wa: WrapE<'a, Result, E0, Self>, ) -> WrapE<'a, A, Result, Self> { Box::pin(async { diff --git a/src/func/local.rs b/src/func/local.rs index 2419699..fb8905b 100644 --- a/src/func/local.rs +++ b/src/func/local.rs @@ -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(state: Self::F>) -> ControlFlow, A> { + fn unstuff( + state: Self::F>, + ) -> ControlFlow, A> { Self::stuff::<_, ControlFlowInstance<_>>(state) } /// Stuff wrapped result into another functor. - fn stuff>(fa: Self::F>) -> T::F>; + fn stuff>(fa: Self::F>) -> T::F>; } diff --git a/src/func/shared.rs b/src/func/shared.rs index d5cb8da..0f61eb1 100644 --- a/src/func/shared.rs +++ b/src/func/shared.rs @@ -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 + Clone; + type Shared: 'a + Send + Sync + Clone; - fn share(fa: Self::F) -> Self::Shared; + fn share(fa: Self::F) -> Self::Shared; - fn unshare(sa: Self::Shared) -> Self::F; + fn unshare(sa: Self::Shared) -> Self::F; } impl<'a, T: 'a + SharedFunctorAny> SharedFunctor<'a> for T { - type Shared = T::SharedAny<'a, A>; + type Shared = T::SharedAny<'a, A>; - fn share(fa: Self::F) -> Self::Shared { + fn share(fa: Self::F) -> Self::Shared { T::share(fa) } - fn unshare(sa: Self::Shared) -> Self::F { + fn unshare(sa: Self::Shared) -> Self::F { T::unshare(sa) } } diff --git a/src/func/test_suite.rs b/src/func/test_suite.rs index 1e43473..93eaeee 100644 --- a/src/func/test_suite.rs +++ b/src/func/test_suite.rs @@ -2,7 +2,7 @@ use super::tests::*; use super::*; pub trait FunctorTestSuite<'a>: WeakFunctor<'a> + Eqr<'a> { - fn sample Self::F)>(f: F); + fn sample Self::F))>(f: F); } pub fn functor_follows_laws<'a, T: Functor<'a> + FunctorTestSuite<'a>>() -> R { diff --git a/src/func/tests.rs b/src/func/tests.rs index 1ec13ae..3db96c0 100644 --- a/src/func/tests.rs +++ b/src/func/tests.rs @@ -27,7 +27,11 @@ impl R { } pub trait Eqr<'a>: WeakFunctor<'a> { - fn eqr(name: &'a str, left: Self::F, right: Self::F) -> R; + fn eqr( + name: &'a str, + left: Self::F, + right: Self::F, + ) -> R; } pub fn eqr(name: &str, left: T, right: T) -> R { @@ -87,7 +91,7 @@ impl AddAssign 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, ) -> 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, ) -> 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, ) -> 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, fg0: impl Fn() -> T::F, @@ -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, - 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, fa0: impl Fn() -> T::F, @@ -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, ) -> 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, fb0: impl 'a + Fn() -> T::F, @@ -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, +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, 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, ) -> 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, - g: impl 'a + Clone + Fn(A) -> T::F, - fa0: impl 'a + Fn() -> T::F, +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, + g: impl 'a + Send + Clone + Fn(A) -> T::F, + fa0: impl Fn() -> T::F, ) -> 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, - fa0: impl 'a + Fn() -> T::F, + fa0: impl 'a + Send + Fn() -> T::F, ) -> 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, + f: impl 'a + Send + Copy + Fn(A) -> B, + fa0: impl Fn() -> T::F, ) -> R { T::eqr( "fmap via bind: fmap f xs = xs >>= return . f", diff --git a/src/func/weakfunctorany.rs b/src/func/weakfunctorany.rs index 36ee7d0..5f2104e 100644 --- a/src/func/weakfunctorany.rs +++ b/src/func/weakfunctorany.rs @@ -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 = T::FAny<'a, A>; + type F = T::FAny<'a, A>; } diff --git a/src/mrds/trees/heighted.rs b/src/mrds/trees/heighted.rs index 68dc056..0deea2d 100644 --- a/src/mrds/trees/heighted.rs +++ b/src/mrds/trees/heighted.rs @@ -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 Display for Node { } struct Reference { - node: Rc>, + node: Arc>, } impl Clone for Reference { @@ -76,11 +76,11 @@ impl Clone for Trees { } } -impl<'a, A: 'a> FunctorContext<'a> for Trees { +impl<'a, A: 'a + Send> FunctorContext<'a> for Trees { type T = instances::solo::SoloInstance; } -impl<'a, A: 'a + Ord + Clone> BinaryTrees<'a> for Trees { +impl<'a, A: 'a + Send + Sync + Ord + Clone> BinaryTrees<'a> for Trees { type Node = Node; type Reference = Reference; @@ -114,17 +114,17 @@ impl<'a, A: 'a + Ord + Clone> BinaryTrees<'a> for Trees { } } -impl<'a, A: 'a + Ord + Clone> BinaryTreesHeight<'a> for Trees { +impl<'a, A: 'a + Send + Sync + Ord + Clone> BinaryTreesHeight<'a> for Trees { fn height(&self, tree: &Self::Tree) -> u64 { tree.height } - fn height_error(&self, error: HeightError) -> BTWrap<'a, Self, T> { + fn height_error(&self, error: HeightError) -> BTWrap<'a, Self, T> { panic!("{error}") } } -impl<'a, A: 'a + Ord + Clone> BinaryTreesEmpty<'a> for Trees { +impl<'a, A: 'a + Send + Sync + Ord + Clone> BinaryTreesEmpty<'a> for Trees { fn empty(&self) -> Self::Tree { Tree { reference: None, @@ -141,7 +141,7 @@ impl<'a, A: 'a + Ord + Clone> BinaryTreesEmpty<'a> for Trees { } } -impl<'a, A: 'a + Ord + Clone> BinaryTreesTryJoin<'a> for Trees { +impl<'a, A: 'a + Send + Sync + Ord + Clone> BinaryTreesTryJoin<'a> for Trees { fn try_join( &self, tl: Self::Tree, @@ -152,17 +152,17 @@ impl<'a, A: 'a + Ord + Clone> BinaryTreesTryJoin<'a> for Trees { } } -impl<'a, A: 'a + Ord + Clone> BinaryTreesUnbalanced<'a> for Trees { +impl<'a, A: 'a + Send + Sync + Ord + Clone> BinaryTreesUnbalanced<'a> for Trees { 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(&self, _error: BalancingError) -> BTWrap<'a, Self, T> { + fn balancing_error(&self, _error: BalancingError) -> BTWrap<'a, Self, T> { panic!("balancing error") } @@ -171,8 +171,11 @@ impl<'a, A: 'a + Ord + Clone> BinaryTreesUnbalanced<'a> for Trees { } } -impl<'a, A: 'a + Ord + Clone> BinaryTreesBindable<'a> for Trees { - fn bounds_error(&self, _error: bounds::BoundsError) -> BTWrap<'a, Self, T> { +impl<'a, A: 'a + Send + Sync + Ord + Clone> BinaryTreesBindable<'a> for Trees { + fn bounds_error( + &self, + _error: bounds::BoundsError, + ) -> BTWrap<'a, Self, T> { panic!("bounds violated"); } } diff --git a/src/mrds/trees/unbalanced.rs b/src/mrds/trees/unbalanced.rs index 1e74cb2..1ec6b8f 100644 --- a/src/mrds/trees/unbalanced.rs +++ b/src/mrds/trees/unbalanced.rs @@ -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>, - cr: Rc>, +pub struct UnbalancedNode<'a, T: Monad<'a>, A: 'a + Send + Sync> { + cl: Arc>, + cr: Arc>, key: A, } -pub type UnbalancedResolution<'a, T, A> = Wrap<'a, Rc>, T>; +pub type UnbalancedResolution<'a, T, A> = Wrap<'a, Arc>, T>; -pub struct UnbalancedReference<'a, T: Monad<'a>, A: 'a>( - Box UnbalancedResolution<'a, T, A>>, +pub struct UnbalancedReference<'a, T: Monad<'a>, A: 'a + Send + Sync>( + Box 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>), + Node(Arc>), } -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) -> Rc> { - Rc::new(UnbalancedTree::Node(Rc::new(UnbalancedReference( + fn to_tree(self: Arc) -> Arc> { + 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>, T> { + fn resolve(&self) -> Wrap<'a, Arc>, T> { ::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>> { + fn refer(&self) -> Option>> { 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>) -> Box UnbalancedResolution<'a, T, A>>, + dyn 'a + + Fn( + Arc>, + ) -> Box 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 { +impl<'a, T: Monad<'a>, A: 'a + Send + Sync> UnbalancedConstructor<'a, T, A> { + pub fn rc(wrap: WrapType<'a, T, A>) -> Arc { Self { wrap }.into() } - pub fn leaf(&self) -> Rc> { + pub fn leaf(&self) -> Arc> { UnbalancedTree::Leaf.into() } pub fn node( - self: &Rc, - cl: Rc>, + self: &Arc, + cl: Arc>, key: A, - cr: Rc>, - ) -> Rc> { - let node = Rc::new(UnbalancedNode { cl, cr, key }); + cr: Arc>, + ) -> Arc> { + 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( - self: &Rc, + self: &Arc, rng: &mut R, slice: &[A], - ) -> Rc> + ) -> Arc> where A: 'a + Clone, { @@ -175,7 +180,7 @@ mod tests { #[test] fn test_simple_slices() { - let ctr: Rc, _>> = + let ctr: Arc, _>> = 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, _>> = + let ctr: Arc, _>> = 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> = + let ctr: Arc> = UnbalancedConstructor::rc(Box::new(|node| { Box::new(move || TracedMonad::pure(node.clone()).after_resolution()) })); diff --git a/src/rcore.rs b/src/rcore.rs index d88c8bb..789c3d7 100644 --- a/src/rcore.rs +++ b/src/rcore.rs @@ -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>, + resolver: &Arc>, ) -> ParseResult<'a, Ctx, Self>; } diff --git a/src/rcore/addresses.rs b/src/rcore/addresses.rs index 1b69f55..da4cf56 100644 --- a/src/rcore/addresses.rs +++ b/src/rcore/addresses.rs @@ -44,7 +44,7 @@ pub(super) trait InliningAddresses: Stream { fn inext_point<'a, Ctx: Context<'a>, A: MentionableBase<'a, Ctx>>( self, addresses: &mut Addresses, - resolver: Rc>, + resolver: Arc>, factory: A::Fctr, err: impl FnOnce(&[u8]) -> E, ) -> Result<(Point<'a, Ctx, A>, Self), E> { @@ -58,7 +58,7 @@ impl InliningAddresses for D {} fn _parse_slice<'a, Ctx: Context<'a>, F: FactoryParse<'a, Ctx>>( factory: &F, slice: &[u8], - resolver: &Rc>, + resolver: &Arc>, ) -> 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>, + resolver: &Arc>, ) -> ParseResult<'a, Ctx, Self> { _parse_slice::(self, slice, resolver) } diff --git a/src/rcore/context.rs b/src/rcore/context.rs index 2822085..84e66c1 100644 --- a/src/rcore/context.rs +++ b/src/rcore/context.rs @@ -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; diff --git a/src/rcore/dectx.rs b/src/rcore/dectx.rs index 9b9b29d..0145214 100644 --- a/src/rcore/dectx.rs +++ b/src/rcore/dectx.rs @@ -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>, + pub resolver: &'c Arc>, pub addresses: &'c mut Addresses, } @@ -13,7 +13,7 @@ pub(super) trait DeCtx<'a, Ctx: Context<'a>> { fn next_address(&mut self) -> Result; - fn resolver(&self) -> Rc>; + fn resolver(&self) -> Arc>; 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> { + fn resolver(&self) -> Arc> { self.resolver.clone() } diff --git a/src/rcore/demoted.rs b/src/rcore/demoted.rs index f8ea809..7b42eb8 100644 --- a/src/rcore/demoted.rs +++ b/src/rcore/demoted.rs @@ -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> { + fn iresolver(&self) -> Arc> { self.0.iresolver() } diff --git a/src/rcore/diagnostic.rs b/src/rcore/diagnostic.rs index 9249bf3..7e2e66f 100644 --- a/src/rcore/diagnostic.rs +++ b/src/rcore/diagnostic.rs @@ -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, event: impl 'b + FnOnce() -> String) -> T::F + fn after<'b, A: 'a + Send>(fa: T::F, event: impl 'b + FnOnce() -> String) -> T::F where 'a: 'b; /// Specify that the evaluation happens before a specific event. - fn before<'b, A: 'a>(fa: T::F, event: impl 'b + FnOnce() -> String) -> T::F + fn before<'b, A: 'a + Send>(fa: T::F, event: impl 'b + FnOnce() -> String) -> T::F where 'a: 'b; /// Label the evaluation step as a specific named action. - fn wrapped<'b, A: 'a>(fa: T::F, event: impl 'b + FnOnce() -> String) -> T::F + fn wrapped<'b, A: 'a + Send>(fa: T::F, event: impl 'b + FnOnce() -> String) -> T::F where 'a: 'b; } diff --git a/src/rcore/inctx.rs b/src/rcore/inctx.rs index 8ecdc9c..8d72c00 100644 --- a/src/rcore/inctx.rs +++ b/src/rcore/inctx.rs @@ -19,7 +19,7 @@ pub trait InCtx<'a, Ctx: Context<'a>>: Stream { } /// Clone the reference to the current [Resolver]. - fn iresolver(&self) -> Rc>; + fn iresolver(&self) -> Arc>; /// 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> { + fn iresolver(&self) -> Arc> { self.resolver() } diff --git a/src/rcore/origin.rs b/src/rcore/origin.rs index ff594a6..34378e2 100644 --- a/src/rcore/origin.rs +++ b/src/rcore/origin.rs @@ -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) -> Resolution<'a, Ctx, Self::Mtbl> + fn resolve(self: Arc) -> 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) -> HashResolution<'a, Ctx>; + fn resolve_bytes(self: Arc) -> HashResolution<'a, Ctx>; } /// Type of the [`Factory`] associated with the [`Origin`]. @@ -19,16 +19,16 @@ pub type OFctr<'a, Ctx, O> = Fctr<'a, Ctx, >::Mtbl>; /// [`OriginMap::resolve_map`]. pub trait OriginMap<'a, Ctx: Context<'a>>: Origin<'a, Ctx> { - fn ref_resolve(self: &Rc) -> Resolution<'a, Ctx, Self::Mtbl> + fn ref_resolve(self: &Arc) -> Resolution<'a, Ctx, Self::Mtbl> where OFctr<'a, Ctx, Self>: FactoryParse<'a, Ctx>, { self.clone().resolve() } - fn resolve_map( - self: &Rc, - f: impl 'a + FnOnce(ResolutionResult<'a, Ctx, Self::Mtbl>) -> T, + fn resolve_map( + self: &Arc, + f: impl 'a + Send + FnOnce(ResolutionResult<'a, Ctx, Self::Mtbl>) -> T, ) -> Wrapped<'a, Ctx, T> where OFctr<'a, Ctx, Self>: FactoryParse<'a, Ctx>, diff --git a/src/rcore/point.rs b/src/rcore/point.rs index fa51f11..ffc73c6 100644 --- a/src/rcore/point.rs +++ b/src/rcore/point.rs @@ -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>, + pub origin: Arc>, } 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( + pub fn resolve_map( &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) } diff --git a/src/rcore/resolution.rs b/src/rcore/resolution.rs index 78ac634..68fb25e 100644 --- a/src/rcore/resolution.rs +++ b/src/rcore/resolution.rs @@ -27,7 +27,7 @@ pub type ResolutionFailure<'a, Ctx, A> = ResolutionError, ParseErrorA<'a, Ctx, A>>; /// Result yielded by [`Origin`]. -pub type ResolutionResult<'a, Ctx, A> = Result, ResolutionFailure<'a, Ctx, A>>; +pub type ResolutionResult<'a, Ctx, A> = Result, 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, Rc>), LookupError<'a, Ctx>>; + Result<(Vec, Arc>), 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, address: Address) -> HashResolution<'a, Ctx>; + fn resolve(self: Arc, 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( - self: Rc, + fn resolve_map( + self: Arc, 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) } diff --git a/src/rcore/resolver_origin.rs b/src/rcore/resolver_origin.rs index e83b4b6..4dd299b 100644 --- a/src/rcore/resolver_origin.rs +++ b/src/rcore/resolver_origin.rs @@ -8,11 +8,11 @@ where pub fn from_address( address: Address, factory: A::Fctr, - resolver: Rc>, + resolver: Arc>, ) -> 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>, + r_resolver: Arc>, } fn _resolve_origin<'a, Ctx: Context<'a>, F: FactoryParse<'a, Ctx>>( - origin: Rc>, + origin: Arc>, ) -> 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) -> Resolution<'a, Ctx, Self::Mtbl> + fn resolve(self: Arc) -> Resolution<'a, Ctx, Self::Mtbl> where F: FactoryParse<'a, Ctx>, { _resolve_origin(self) } - fn resolve_bytes(self: Rc) -> HashResolution<'a, Ctx> { + fn resolve_bytes(self: Arc) -> HashResolution<'a, Ctx> { self.r_resolver.clone().resolve(self.r_address) } } diff --git a/src/rstd.rs b/src/rstd.rs index 1a4babc..15c22c4 100644 --- a/src/rstd.rs +++ b/src/rstd.rs @@ -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 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>; + /// Wrap the resolver into [`Arc`]. + fn into_rc(self) -> Arc>; } impl<'a, Ctx: Context<'a>, R: Resolver<'a, Ctx>> ResolverExt<'a, Ctx> for R { - fn into_rc(self) -> Rc> { - Rc::new(self) + fn into_rc(self) -> Arc> { + Arc::new(self) } } diff --git a/src/rstd/cast.rs b/src/rstd/cast.rs index 46fabf6..a67fca7 100644 --- a/src/rstd/cast.rs +++ b/src/rstd/cast.rs @@ -83,8 +83,8 @@ impl<'a> CastError<'a> { } impl<'a, Ctx: CastCtx<'a>> CastResolver<'a, Ctx> { - fn rc(points: Vec>>) -> Rc> { - Rc::new(Self { points }) + fn rc(points: Vec>>) -> Arc> { + 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, address: Address) -> HashResolution<'a, Ctx> { + fn resolve(self: Arc, address: Address) -> HashResolution<'a, Ctx> { let point = match self.get_point(address) { Ok(point) => point, Err(cast_error) => return cast_error.pure::(), @@ -151,7 +151,7 @@ impl<'a, Ctx: CastCtx<'a>> TypelessMentionable<'a, Ctx> { pub fn cast_full>( &self, factory: A::Fctr, - map_resolver: impl FnOnce(Rc>) -> Rc>, + map_resolver: impl FnOnce(Arc>) -> Arc>, ) -> 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>>, + typeless_origin: Arc>>, 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>>, + typeless_origin: Arc>>, factory: A::Fctr, -) -> Rc> { +) -> Arc> { 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>( &self, factory: A::Fctr, - ) -> Rc> { + ) -> Arc> { let typeless_origin = self.origin.clone(); cast_origin(typeless_origin, factory) } diff --git a/src/rstd/collections/stack.rs b/src/rstd/collections/stack.rs index 2a00bb3..cdd840a 100644 --- a/src/rstd/collections/stack.rs +++ b/src/rstd/collections/stack.rs @@ -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 = make_stack(); let count = stack.clone().vec().count(); assert_eq!(count, 0); - let stack: T = Rc::new(stack).delay()?; + let stack: T = 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 = Rc::new(stack).trace()?; + let stack: T = 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 = Rc::new(stack).trace()?; + let stack: T = Arc::new(stack).trace()?; let rendered = stack.clone().vec().render(); assert_eq!(rendered.length(), 3); assert_eq!(rendered.width(), 1); diff --git a/src/rstd/collections/tree/context.rs b/src/rstd/collections/tree/context.rs index 495f111..1fcc448 100644 --- a/src/rstd/collections/tree/context.rs +++ b/src/rstd/collections/tree/context.rs @@ -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 } } -pub type TreeContext2<'a, Ctx, A, C, E> = TreeContext<(Rc, Fctr<'a, Ctx, A>), (Ctx, A, E)>; +pub type TreeContext2<'a, Ctx, A, C, E> = TreeContext<(Arc, Fctr<'a, Ctx, A>), (Ctx, A, E)>; -impl<'a, Ctx: Context<'a>, A: Mentionable<'a, Ctx> + Clone, C: 'a + Comparator, E: 'a> - FunctorContext<'a> for TreeContext2<'a, Ctx, A, C, E> +impl< + 'a, + Ctx: Context<'a>, + A: Mentionable<'a, Ctx> + Clone, + C: 'a + Comparator, + 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, E: 'a> - BinaryTrees<'a> for TreeContext2<'a, Ctx, A, C, E> +impl< + 'a, + Ctx: Context<'a>, + A: Mentionable<'a, Ctx> + Clone, + C: 'a + Comparator, + 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: Mentionable<'a, Ctx> + Clone, C: 'a + Comparator, E: 'a> - BinaryTreesEmpty<'a> for TreeContext2<'a, Ctx, A, C, E> +impl< + 'a, + Ctx: Context<'a>, + A: Mentionable<'a, Ctx> + Clone, + C: 'a + Comparator, + 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: Mentionable<'a, Ctx> + Clone, C: 'a + Comparator, E: 'a> - BinaryTreesHeight<'a> for TreeContext2<'a, Ctx, A, C, E> +impl< + 'a, + Ctx: Context<'a>, + A: Mentionable<'a, Ctx> + Clone, + C: 'a + Comparator, + E: 'a + Send, + > BinaryTreesHeight<'a> for TreeContext2<'a, Ctx, A, C, E> { fn height(&self, tree: &Self::Tree) -> u64 { tree.height } - fn height_error(&self, error: HeightError) -> BTWrap<'a, Self, T> { + fn height_error(&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> } } -impl<'a, Ctx: Context<'a>, A: Mentionable<'a, Ctx> + Clone, C: 'a + Comparator, E: 'a> - BinaryTreesUnbalanced<'a> for TreeContext2<'a, Ctx, A, C, WrappedExtra> +impl< + 'a, + Ctx: Context<'a>, + A: Mentionable<'a, Ctx> + Clone, + C: 'a + Comparator, + E: 'a + Send, + > BinaryTreesUnbalanced<'a> for TreeContext2<'a, Ctx, A, C, WrappedExtra> { 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(&self, error: BalancingError) -> BTWrap<'a, Self, T> { + fn balancing_error(&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: Mentionable<'a, Ctx> + Clone, C: 'a + Comparator, E: 'a> - BinaryTreesBindable<'a> for TreeContext2<'a, Ctx, A, C, WrappedExtra, E>> +impl< + 'a, + Ctx: Context<'a>, + A: Mentionable<'a, Ctx> + Clone, + C: 'a + Comparator, + E: 'a + Send, + > BinaryTreesBindable<'a> for TreeContext2<'a, Ctx, A, C, WrappedExtra, E>> { - fn bounds_error(&self, error: BoundsError) -> BTWrap<'a, Self, T> { + fn bounds_error(&self, error: BoundsError) -> BTWrap<'a, Self, T> { Self::fail(error.into()) } } diff --git a/src/rstd/inject.rs b/src/rstd/inject.rs index 7d34f65..80816aa 100644 --- a/src/rstd/inject.rs +++ b/src/rstd/inject.rs @@ -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(&self, fa: Wrapped<'a, Ctx, A>) -> Wrapped<'a, Ctx, A>; +pub trait Inject<'a, Ctx: Context<'a>>: 'a + Send + Sync + Sized { + fn inject(&self, fa: Wrapped<'a, Ctx, A>) -> Wrapped<'a, Ctx, A>; fn inject_mentionable>( - self: Rc, + self: Arc, 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>, - inject: Rc, + resolver: Arc>, + inject: Arc, } impl<'a, Ctx: Context<'a>, F: Inject<'a, Ctx>> Resolver<'a, Ctx> for InjectedResolver<'a, Ctx, F> { - fn resolve(self: Rc, address: Address) -> HashResolution<'a, Ctx> { + fn resolve(self: Arc, address: Address) -> HashResolution<'a, Ctx> { let inject = self.inject.clone(); self.inject.inject( self.resolver diff --git a/src/rstd/inlining/static_pair.rs b/src/rstd/inlining/static_pair.rs index 5764778..6b8ebf3 100644 --- a/src/rstd/inlining/static_pair.rs +++ b/src/rstd/inlining/static_pair.rs @@ -30,7 +30,7 @@ pub trait StaticPairSerializable { /// /// Note: [`StaticPair::FA`] requires [`InliningFactory`] be implemented. pub trait StaticPair<'a, Ctx: Context<'a>>: - 'a + StaticPairSerializable + Sized + 'a + Send + Sync + StaticPairSerializable + 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; /// Regularise the error returned while parsing the first element. diff --git a/src/rstd/local_origin.rs b/src/rstd/local_origin.rs index 118dfc9..280bf60 100644 --- a/src/rstd/local_origin.rs +++ b/src/rstd/local_origin.rs @@ -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>) -> Self { + fn from_fields(point: Hash, origin: Arc>) -> Self { Point { point, origin } } fn from_values>(point: Hash, origin: O) -> Self { - Self::from_fields(point, Rc::new(origin)) + Self::from_fields(point, Arc::new(origin)) } - fn from_mentionable(mentionable: Rc) -> Self { + fn from_mentionable(mentionable: Arc) -> 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(Rc); +struct LocalOrigin(Arc); impl<'a, Ctx: Context<'a>, A: Mentionable<'a, Ctx>> Origin<'a, Ctx> for LocalOrigin { 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) -> Resolution<'a, Ctx, Self::Mtbl> { + fn resolve(self: Arc) -> Resolution<'a, Ctx, Self::Mtbl> { Ctx::pure(Ok(self.0.clone())) } - fn resolve_bytes(self: Rc) -> HashResolution<'a, Ctx> { + fn resolve_bytes(self: Arc) -> 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 From> for LocalOrigin { - fn from(value: Rc) -> Self { +impl From> for LocalOrigin { + fn from(value: Arc) -> Self { LocalOrigin(value) } } -impl<'a, Ctx: Context<'a>, A: Mentionable<'a, Ctx>> From> for Point<'a, Ctx, A> { - fn from(value: Rc) -> Self { +impl<'a, Ctx: Context<'a>, A: Mentionable<'a, Ctx>> From> for Point<'a, Ctx, A> { + fn from(value: Arc) -> Self { Self::from_mentionable(value) } } diff --git a/src/rstd/nullable.rs b/src/rstd/nullable.rs index 50795e2..874c628 100644 --- a/src/rstd/nullable.rs +++ b/src/rstd/nullable.rs @@ -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) -> Self { + fn from_mentionable(mentionable: Arc) -> Self { Self::NotNull(mentionable.into()) } @@ -142,8 +142,8 @@ impl AlwaysConstSize for NullableFactory { const _SIZE: usize = HASH_SIZE; } -impl<'a, Ctx: Context<'a>, A: Mentionable<'a, Ctx>> From> for Nullable<'a, Ctx, A> { - fn from(value: Rc) -> Self { +impl<'a, Ctx: Context<'a>, A: Mentionable<'a, Ctx>> From> for Nullable<'a, Ctx, A> { + fn from(value: Arc) -> Self { Self::from_mentionable(value) } } diff --git a/src/rstd/singular.rs b/src/rstd/singular.rs index 42e5367..13276ed 100644 --- a/src/rstd/singular.rs +++ b/src/rstd/singular.rs @@ -1,8 +1,9 @@ use crate::rcore::*; -use crate::rstd::*; -trait SingularResolution<'a, Ctx: Context<'a>>: 'a { - fn singular(self: Rc) -> HashResolution<'a, Ctx>; +use super::*; + +trait SingularResolution<'a, Ctx: Context<'a>>: 'a + Send + Sync { + fn singular(self: Arc) -> 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) -> HashResolution<'a, Ctx> { + fn singular(self: Arc) -> 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>>, + points: Vec>>, } 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, address: Address) -> HashResolution<'a, Ctx> { + fn resolve(self: Arc, 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>> { +impl<'a, Ctx: Context<'a>> PointsVisitor<'a, Ctx> for Vec>> { fn visit>(&mut self, point: &Point<'a, Ctx, A>) { - self.push(Rc::new(point.clone()) as _); + self.push(Arc::new(point.clone()) as _); } } diff --git a/src/rstd/tracing/traceable.rs b/src/rstd/tracing/traceable.rs index f73ef24..7befc9f 100644 --- a/src/rstd/tracing/traceable.rs +++ b/src/rstd/tracing/traceable.rs @@ -5,7 +5,7 @@ use super::*; struct TracedInject; impl<'a, Ctx: Context<'a, _Tm = TracedInstance>> Inject<'a, Ctx> for TracedInject { - fn inject(&self, fa: Wrapped<'a, Ctx, A>) -> Wrapped<'a, Ctx, A> { + fn inject(&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) } } diff --git a/src/rstd/typeless.rs b/src/rstd/typeless.rs index 4a2f48f..81aca8b 100644 --- a/src/rstd/typeless.rs +++ b/src/rstd/typeless.rs @@ -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>>, } -type TypelessParsed<'a, Ctx> = Result, Box>; +type TypelessParsed<'a, Ctx> = Result, Box>; 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); +pub struct TypelessError<'a>(Box); 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>(mentionable: Rc) -> Self { + pub fn from_typed>(mentionable: Arc) -> 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(error: E) -> Self { + pub fn from_typed(error: E) -> Self { TypelessError(Box::new(error)) } } diff --git a/src/rstd/wrapped_origin.rs b/src/rstd/wrapped_origin.rs index 71f1e99..250c534 100644 --- a/src/rstd/wrapped_origin.rs +++ b/src/rstd/wrapped_origin.rs @@ -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> { - Rc::new(WrappedOrigin { + resolve: impl 'a + Send + Sync + Fn() -> Resolution<'a, Ctx, A>, + resolve_bytes: impl 'a + Send + Sync + Fn() -> HashResolution<'a, Ctx>, +) -> Arc> { + 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>( - self: Rc, - map_ok: impl 'a + Send + Sync + Clone + Fn(Rc) -> B, + self: Arc, + map_ok: impl 'a + Send + Sync + Clone + Fn(Arc) -> 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> + ) -> Arc> 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) -> 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) -> 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 Resolution<'a, Ctx, A>>, - w_resolve_bytes: Box HashResolution<'a, Ctx>>, + w_resolve: Box Resolution<'a, Ctx, A>>, + w_resolve_bytes: Box 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) -> Resolution<'a, Ctx, A> { + fn resolve(self: Arc) -> Resolution<'a, Ctx, A> { (self.w_resolve)() } - fn resolve_bytes(self: Rc) -> HashResolution<'a, Ctx> { + fn resolve_bytes(self: Arc) -> HashResolution<'a, Ctx> { (self.w_resolve_bytes)() } } diff --git a/src/testing.rs b/src/testing.rs index ecdf930..f0e3c33 100644 --- a/src/testing.rs +++ b/src/testing.rs @@ -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, _event: impl 'b + FnOnce() -> String) -> T::F { + fn after<'b, A: 'a + Send>(fa: T::F, _event: impl 'b + FnOnce() -> String) -> T::F { fa } - fn before<'b, A>(fa: T::F, _event: impl 'b + FnOnce() -> String) -> T::F { + fn before<'b, A: 'a + Send>(fa: T::F, _event: impl 'b + FnOnce() -> String) -> T::F { fa } - fn wrapped<'b, A>(fa: T::F, _event: impl 'b + FnOnce() -> String) -> T::F { + fn wrapped<'b, A: 'a + Send>(fa: T::F, _event: impl 'b + FnOnce() -> String) -> T::F { 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, address: Address) -> HashResolution<'a, TestContextPlain> { + fn resolve(self: Arc, 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(&self, fa: Wrapped<'a, Ctx, A>) -> Wrapped<'a, Ctx, A> { + fn inject(&self, fa: Wrapped<'a, Ctx, A>) -> Wrapped<'a, Ctx, A> { fa } } -pub fn reparse<'a, A: Mentionable<'a, TestContextPlain>>(mentionable: Rc) -> A { - Rc::new(EmptyInject) +pub fn reparse<'a, A: Mentionable<'a, TestContextPlain>>(mentionable: Arc) -> A { + Arc::new(EmptyInject) .inject_mentionable(mentionable.as_ref()) .expect("re-parsing failed") } diff --git a/src/testing/counted.rs b/src/testing/counted.rs index 14ed990..2f3fb56 100644 --- a/src/testing/counted.rs +++ b/src/testing/counted.rs @@ -61,7 +61,7 @@ impl Counted { struct CountedInject; impl<'a> Inject<'a, TestContextCounted> for CountedInject { - fn inject( + fn inject( &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) } }