diff --git a/book-monads b/book-monads index f1dd33d..b96a072 160000 --- a/book-monads +++ b/book-monads @@ -1 +1 @@ -Subproject commit f1dd33d61f7d1ce9c1d428ff0d75fb3efb2bb340 +Subproject commit b96a072b3a80e689cb99dc6e9922add0d6d93c87 diff --git a/radn-derive/src/lib.rs b/radn-derive/src/lib.rs index bd29b0d..3a1ee85 100644 --- a/radn-derive/src/lib.rs +++ b/radn-derive/src/lib.rs @@ -39,22 +39,3 @@ fn add_clone_bounds(mut generics: Generics) -> Generics { } generics } - -#[proc_macro_derive(CovariantFunctor)] -pub fn derive_covariant_functor(input: proc_macro::TokenStream) -> proc_macro::TokenStream { - let input = parse_macro_input!(input as DeriveInput); - let name = input.ident; - let generics = input.generics; - let (impl_generics, ty_generics, where_clause) = generics.split_for_impl(); - let expanded = quote! { - impl #impl_generics CovariantFunctor for #name #ty_generics #where_clause { - fn variate<'a: 'b, 'b, A: 'a>(fa: Self::F<'a, A>) -> Self::F<'b, A> - where - Self: 'a, - { - fa - } - } - }; - proc_macro::TokenStream::from(expanded) -} diff --git a/src/flow/traversible/algorithms/contains.rs b/src/flow/traversible/algorithms/contains.rs index 8fbf70f..e045286 100644 --- a/src/flow/traversible/algorithms/contains.rs +++ b/src/flow/traversible/algorithms/contains.rs @@ -4,7 +4,7 @@ pub fn n_contains<'a, T: MonadFail<'a, ()>, A: 'a, D: 'a + PartialEq>( comparator: &'a dyn Comparator, n_set: Rc>, key: Rc, -) -> T::F<'a, ()> { +) -> T::Fa<()> { let (t_setl, t_setr, k_set) = n_set.split(); match comparator.pick_smaller(key.as_ref(), k_set.as_ref()) { Comparison::L => t_contains(comparator, t_setl, key), @@ -17,7 +17,7 @@ pub fn r_contains<'a, T: MonadFail<'a, ()>, A: 'a, D: 'a + PartialEq>( comparator: &'a dyn Comparator, r_set: Rc>, key: Rc, -) -> T::F<'a, ()> { +) -> T::Fa<()> { T::bind(r_set.resolve(), |n_set| n_contains(comparator, n_set, key)) } @@ -25,7 +25,7 @@ pub fn t_contains<'a, T: MonadFail<'a, ()>, A: 'a, D: 'a + PartialEq>( comparator: &'a dyn Comparator, t_set: Rc>, key: Rc, -) -> T::F<'a, ()> { +) -> T::Fa<()> { match t_set.refer() { Some(r_set) => r_contains(comparator, r_set, key), None => T::fail(()), diff --git a/src/flow/traversible/algorithms/subset.rs b/src/flow/traversible/algorithms/subset.rs index 4f49071..273304d 100644 --- a/src/flow/traversible/algorithms/subset.rs +++ b/src/flow/traversible/algorithms/subset.rs @@ -12,7 +12,7 @@ struct SubsetContext<'a, T: MonadFail<'a, ()>, A: 'a, D: 'a + PartialEq> { } impl<'a, T: 'a + MonadFail<'a, ()>, A: 'a, 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<'a, ()> { + fn on_l(self, (t_subl, t_subr, k_sub): Split<'a, T, A, D>) -> T::Fa<()> { T::la2( and, algorithms::contains::t_contains(self.comparator, self.t_superl.clone(), k_sub.clone()), @@ -36,7 +36,7 @@ impl<'a, T: 'a + MonadFail<'a, ()>, A: 'a, D: 'a + PartialEq> SubsetContext<'a, ) } - fn on_e(self, (t_subl, t_subr, k_sub): Split<'a, T, A, D>) -> T::F<'a, ()> { + fn on_e(self, (t_subl, t_subr, k_sub): Split<'a, T, A, D>) -> T::Fa<()> { T::la2( and, t_subset_of_t( @@ -56,7 +56,7 @@ impl<'a, T: 'a + MonadFail<'a, ()>, A: 'a, D: 'a + PartialEq> SubsetContext<'a, ) } - fn on_r(self, (t_subl, t_subr, k_sub): Split<'a, T, A, D>) -> T::F<'a, ()> { + fn on_r(self, (t_subl, t_subr, k_sub): Split<'a, T, A, D>) -> T::Fa<()> { T::la2( and, algorithms::contains::t_contains(self.comparator, self.t_superr.clone(), k_sub.clone()), @@ -80,7 +80,7 @@ impl<'a, T: 'a + MonadFail<'a, ()>, A: 'a, D: 'a + PartialEq> SubsetContext<'a, ) } - fn test(self) -> T::F<'a, ()> { + fn test(self) -> T::Fa<()> { let split = self.n_subset.split(); match self .comparator @@ -99,7 +99,7 @@ pub fn n_subset_of_n<'a, T: MonadFail<'a, ()>, A: 'a, D: 'a + PartialEq>( n_superset: Rc>, k_l: Option>, k_r: Option>, -) -> T::F<'a, ()> { +) -> T::Fa<()> { let (t_superl, t_superr, k_super) = n_superset.split(); if let Some(ref a_l) = k_l { if let Comparison::R = comparator.pick_smaller(a_l.as_ref(), k_super.as_ref()) { @@ -130,7 +130,7 @@ pub fn r_subset_of_r<'a, T: MonadFail<'a, ()>, A: 'a, D: 'a + PartialEq>( r_superset: Rc>, k_l: Option>, k_r: Option>, -) -> T::F<'a, ()> { +) -> T::Fa<()> { T::join(T::la2( move |n_subset, n_superset| n_subset_of_n(comparator, n_subset, n_superset, k_l, k_r), r_subset.resolve(), @@ -144,7 +144,7 @@ pub fn t_subset_of_t<'a, T: MonadFail<'a, ()>, A, D: 'a + PartialEq>( t_superset: Rc>, k_l: Option>, k_r: Option>, -) -> T::F<'a, ()> { +) -> T::Fa<()> { match (t_subset.refer(), t_superset.refer()) { (None, _) => T::pure(()), (Some(_), None) => T::fail(()), diff --git a/src/func.rs b/src/func.rs index 840dac6..fe464b6 100644 --- a/src/func.rs +++ b/src/func.rs @@ -21,7 +21,7 @@ pub mod tests; pub use std::ops::ControlFlow; -pub use radn_derive::{CovariantFunctor, SharedFunctor}; +pub use radn_derive::SharedFunctor; pub use self::applicative_select::{ ApplicativeSelect, ApplicativeSelectExt, Selected, SelectedWrapped, @@ -31,9 +31,6 @@ pub use self::controlflow::{Iterative, IterativeWrapped}; #[cfg(doc)] use self::instances::stackless::StacklessInstance; -/// Part of Haskell's `Functor f` responsible for having `f a`. -/// -/// pub trait WeakFunctor { /// Type of the wrapped value. type F<'a, A: 'a>: 'a @@ -41,6 +38,9 @@ pub trait WeakFunctor { Self: 'a; } +/// Part of Haskell's `Functor f` responsible for having `f a`. +/// +/// pub trait WeakFunctorA<'a>: 'a { type Fa: 'a; } @@ -53,59 +53,20 @@ pub type Wrap<'a, A, T> = >::Fa; /// Rust-specific implementation of [`Functor`], respecting `move` semantics. /// -/// Cannot insantiate for e.g. multi-element collections: -/// ```compile_fail -/// use radn_rs::func::*; -/// -/// struct VecInstance; -/// -/// impl WeakFunctor for VecInstance { -/// type F<'a, A> = Vec; -/// } -/// -/// impl Functor for VecInstance { -/// fn fmap<'a, A: 'a, B: 'a>(f: impl 'a + FnOnce(A) -> B, fa: Self::F<'a, A>) -> Self::F<'a, B> { -/// fa.into_iter().map(f).collect() -/// } -/// } -/// ``` -/// Why does it fail to compile? `.map` expects `FnMut` (or we can think of it being `Fn`, doesn't matter here). -/// But what we provide it (`f`) is only `FnOnce`. -/// -/// For Haskell-style Functors, use [`clone_func::CloneFunctor`] instead. -/// ``` -/// use radn_rs::func::clone_func::*; -/// -/// struct VecInstance; -/// -/// impl CloneWeakFunctor for VecInstance { -/// type ClF<'a, A: Clone> = Vec; -/// } -/// -/// impl CloneFunctor for VecInstance { -/// fn clone_fmap<'a, A: 'a + Clone, B: 'a + Clone>( -/// f: impl 'a + Fn(A) -> B, -/// fa: Self::ClF<'a, A>, -/// ) -> Self::ClF<'a, B> { -/// fa.into_iter().map(f).collect() -/// } -/// } -/// ``` -/// /// -pub trait Functor<'a>: 'a + WeakFunctor { +pub trait Functor<'a>: WeakFunctorA<'a> { /// Equivalent or Haskell's `fmap`. /// Due to Rust limitations, it's not a `function->function` conversion. /// For that see [`derivations::fmap`]. - fn fmap(f: impl 'a + FnOnce(A) -> B, fa: Self::F<'a, A>) -> Self::F<'a, B>; + fn fmap(f: impl 'a + FnOnce(A) -> B, fa: Self::Fa) -> Self::Fa; /// Equivalent of Haskell's `$>`/`<$`. - fn replace(fa: Self::F<'a, A>, b: B) -> Self::F<'a, B> { + fn replace(fa: Self::Fa, b: B) -> Self::Fa { Self::fmap(|_| b, fa) } /// Equivalent of Haskell's `void`. - fn void(fa: Self::F<'a, A>) -> Self::F<'a, ()> { + fn void(fa: Self::Fa) -> Self::Fa<()> { Self::replace(fa, ()) } } @@ -113,16 +74,13 @@ pub trait Functor<'a>: 'a + WeakFunctor { /// 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<'a, A>; + fn pure(a: A) -> Self::Fa; } /// Part of [`Applicative`] responsible for Haskell's sequential application `<*>`. pub trait ApplicativeSeq<'a>: Functor<'a> { /// Equivalent of Haskell's `<*>`. - fn seq( - ff: Self::F<'a, impl 'a + FnOnce(A) -> B>, - fa: Self::F<'a, A>, - ) -> Self::F<'a, B>; + fn seq(ff: Self::Fa B>, fa: Self::Fa) -> Self::Fa; } /// Part of [`Applicative`] responsible for Haskell's result combination `listA2`. @@ -130,15 +88,15 @@ pub trait ApplicativeLA2<'a>: Functor<'a> { /// Equivalent of Haskell's `listA2`. fn la2( f: impl 'a + FnOnce(A, B) -> C, - fa: Self::F<'a, A>, - fb: Self::F<'a, B>, - ) -> Self::F<'a, C>; + fa: Self::Fa, + fb: Self::Fa, + ) -> Self::Fa; } /// 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<'a, A>, Self::F<'a, B>)) -> Self::F<'a, (A, B)>; + fn tuple(fab: (Self::Fa, Self::Fa)) -> Self::Fa<(A, B)>; } /// Equivalent of Haskell's `Applicative`. @@ -149,12 +107,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<'a, A>, fb: Self::F<'a, B>) -> Self::F<'a, B> { + fn discard_first(fa: Self::Fa, fb: Self::Fa) -> Self::Fa { Self::seq(Self::replace(fa, |b| b), fb) } /// Equivalent of Haskell's `<*`. - fn discard_second(fa: Self::F<'a, A>, fb: Self::F<'a, B>) -> Self::F<'a, A> { + fn discard_second(fa: Self::Fa, fb: Self::Fa) -> Self::Fa { Self::la2(|a, _| a, fa, fb) } } @@ -166,19 +124,16 @@ 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<'a, A>, - f: impl 'a + FnOnce(A) -> Self::F<'a, B>, - ) -> Self::F<'a, B>; + fn bind(fa: Self::Fa, f: impl 'a + FnOnce(A) -> Self::Fa) -> Self::Fa; /// Included for optimisation and clarity. /// Generally, [`Monad::bind`] should be enough implement it. /// See [`StacklessInstance::iterate`] for a generic, though less-than ideal, blanket implementation. /// On practice, you generally shouldn't be using [`Monad::bind`]/[`Pure::pure`]/[`Functor::fmap`] here. - fn iterate(f: impl Iterative<'a, T = Self, B = B>) -> Self::F<'a, B>; + fn iterate(f: impl Iterative<'a, T = Self, B = B>) -> Self::Fa; /// Equivalent of Haskell's `join`. - fn join(ffa: Self::F<'a, Self::F<'a, A>>) -> Self::F<'a, A> { + fn join(ffa: Self::Fa>) -> Self::Fa { Self::bind(ffa, |fa| fa) } } @@ -190,8 +145,8 @@ pub trait MonadExt<'a>: Monad<'a> { /// rather than some dedicated state type. fn iterate_mut( a: A, - f: impl 'a + FnMut(A) -> Self::F<'a, ControlFlow>, - ) -> Self::F<'a, B> { + f: impl 'a + FnMut(A) -> Self::Fa>, + ) -> Self::Fa { Self::iterate(BindableMut::new(a, f)) } } @@ -199,9 +154,9 @@ pub trait MonadExt<'a>: Monad<'a> { impl<'a, T: Monad<'a>> MonadExt<'a> for T {} /// Part of [`MonadFail`] responsible for Haskell's `fail`. -pub trait Fail<'a, E: 'a>: 'a + WeakFunctor { +pub trait Fail<'a, E: 'a>: WeakFunctorA<'a> { /// Equivalent of Haskell's `fail`. - fn fail(e: E) -> Self::F<'a, A>; + fn fail(e: E) -> Self::Fa; } /// Equivalent of Haskell's `MonadFail`. Auto-implemented for all [`Fail`]`+`[`Monad`]. @@ -212,21 +167,14 @@ pub trait MonadFail<'a, E: 'a>: Monad<'a> + Fail<'a, E> {} impl<'a, E: 'a, T: Monad<'a> + Fail<'a, E>> MonadFail<'a, E> for T {} /// Represents wrapped results which are instantly available. -pub trait LocalFunctor: WeakFunctor { +pub trait LocalFunctor<'a>: WeakFunctorA<'a> { /// Extract iteration state, if successful. - fn unstuff<'a, A: 'a, B: 'a>( - state: Self::F<'a, ControlFlow>, - ) -> ControlFlow, A> - where - Self: 'a, - { + fn unstuff(state: Self::Fa>) -> ControlFlow, A> { Self::stuff::<_, ControlFlowInstance>(state) } /// Stuff wrapped result into another functor. - fn stuff<'a, A: 'a, T: Pure<'a>>(fa: Self::F<'a, T::F<'a, A>>) -> T::F<'a, Self::F<'a, A>> - where - Self: 'a; + fn stuff>(fa: Self::Fa>) -> T::Fa>; } /// Represents a (collection of) [Monad]\(s) that can hold any type of error. @@ -334,8 +282,10 @@ pub trait SharedFunctor: WeakFunctor { Self: 'a; } -pub trait CovariantFunctor: WeakFunctor { - fn variate<'a: 'b, 'b, A: 'a>(fa: Self::F<'a, A>) -> Self::F<'b, A> - where - Self: 'a; +pub trait SharedFunctorA<'a>: WeakFunctorA<'a> { + type SharedA: 'a + Clone; + + fn share(fa: Self::Fa) -> Self::SharedA; + + fn unshare(sa: Self::SharedA) -> Self::Fa; } diff --git a/src/func/applicative_select.rs b/src/func/applicative_select.rs index 317c26f..3e986ba 100644 --- a/src/func/applicative_select.rs +++ b/src/func/applicative_select.rs @@ -1,17 +1,14 @@ use super::*; -pub enum Selected<'a, A: 'a, B: 'a, T: ?Sized + 'a + WeakFunctor> { - A(A, T::F<'a, B>), - B(T::F<'a, A>, B), +pub enum Selected<'a, A: 'a, B: 'a, T: ?Sized + WeakFunctorA<'a>> { + A(A, T::Fa), + B(T::Fa, B), } pub type SelectedWrapped<'a, A, B, T> = Wrap<'a, Selected<'a, A, B, T>, T>; pub trait ApplicativeSelect<'a>: Functor<'a> { - fn select( - fa: Self::F<'a, A>, - fb: Self::F<'a, B>, - ) -> SelectedWrapped<'a, A, B, Self> { + fn select(fa: Self::Fa, fb: Self::Fa) -> SelectedWrapped<'a, A, B, Self> { Self::fmap(|a| Selected::A(a, fb), fa) } } @@ -19,9 +16,9 @@ pub trait ApplicativeSelect<'a>: Functor<'a> { pub trait ApplicativeSelectExt<'a>: ApplicativeSelect<'a> { fn select_map( f: impl 'a + FnOnce(Selected<'a, A, B, Self>) -> C, - fa: Self::F<'a, A>, - fb: Self::F<'a, B>, - ) -> Self::F<'a, C> { + fa: Self::Fa, + fb: Self::Fa, + ) -> Self::Fa { Self::fmap(f, Self::select(fa, fb)) } } diff --git a/src/func/controlflow.rs b/src/func/controlflow.rs index 3a718b0..d001ac4 100644 --- a/src/func/controlflow.rs +++ b/src/func/controlflow.rs @@ -11,7 +11,7 @@ impl WeakFunctor for ControlFlowInstance { } impl<'a, C: 'a> Functor<'a> for ControlFlowInstance { - fn fmap(f: impl 'a + FnOnce(A) -> B, fa: Self::F<'a, A>) -> Self::F<'a, B> { + fn fmap(f: impl 'a + FnOnce(A) -> B, fa: Self::Fa) -> Self::Fa { match fa { ControlFlow::Continue(c) => ControlFlow::Continue(c), ControlFlow::Break(a) => ControlFlow::Break(f(a)), @@ -20,33 +20,23 @@ impl<'a, C: 'a> Functor<'a> for ControlFlowInstance { } impl<'a, C: 'a> Pure<'a> for ControlFlowInstance { - fn pure(a: A) -> Self::F<'a, A> { + fn pure(a: A) -> Self::Fa { 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<'a, ControlFlow>, - > BindableMut +impl<'a, T: ?Sized + Functor<'a>, A: 'a, B: 'a, F: 'a + FnMut(A) -> T::Fa>> + 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<'a, ControlFlow>, - > Iterative<'a> for BindableMut +impl<'a, T: ?Sized + Functor<'a>, A: 'a, B: 'a, F: 'a + FnMut(A) -> T::Fa>> + Iterative<'a> for BindableMut { type B = B; type T = T; @@ -74,7 +64,7 @@ pub trait Iterative<'a>: 'a + Sized { /// [`ControlFlow::Break`]. type B: 'a; /// Corresponding [`WeakFunctor`]. - type T: 'a + ?Sized + WeakFunctor; + type T: ?Sized + WeakFunctorA<'a>; /// Get next state. fn next(self) -> IterativeWrapped<'a, Self>; } diff --git a/src/func/derivations.rs b/src/func/derivations.rs index 7311a4f..7e879d8 100644 --- a/src/func/derivations.rs +++ b/src/func/derivations.rs @@ -5,23 +5,23 @@ 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, -) -> impl FnOnce(T::F<'a, A>) -> T::F<'a, B> { +) -> impl FnOnce(Wrap<'a, A, T>) -> Wrap<'a, B, T> { move |fa| T::fmap(f, fa) } /// 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<'a, B>, -) -> impl FnOnce(T::F<'a, A>) -> T::F<'a, B> { + f: impl 'a + FnOnce(A) -> T::Fa, +) -> 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, - fa: Self::F<'a, A>, - fb: Self::F<'a, B>, - ) -> Self::F<'a, C> { + fa: Self::Fa, + fb: Self::Fa, + ) -> Self::Fa { Self::seq(Self::fmap(|a| |b| f(a, b), fa), fb) } } @@ -30,9 +30,9 @@ impl<'a, T: ApplicativeSeq<'a>> ApplicativeLA2ViaSeq<'a> for T {} pub trait ApplicativeSeqViaLA2<'a>: ApplicativeLA2<'a> { fn _seq_via_la2( - ff: Self::F<'a, impl 'a + FnOnce(A) -> B>, - fa: Self::F<'a, A>, - ) -> Self::F<'a, B> { + ff: Self::Fa B>, + fa: Self::Fa, + ) -> Self::Fa { Self::la2(|f, a| f(a), ff, fa) } } @@ -40,9 +40,7 @@ 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<'a, A>, Self::F<'a, B>), - ) -> Self::F<'a, (A, B)> { + fn _tuple_via_la2((fa, fb): (Self::Fa, Self::Fa)) -> Self::Fa<(A, B)> { Self::la2(|a, b| (a, b), fa, fb) } } diff --git a/src/func/instances/composition.rs b/src/func/instances/composition.rs index ebce675..b447206 100644 --- a/src/func/instances/composition.rs +++ b/src/func/instances/composition.rs @@ -2,26 +2,26 @@ use crate::func::*; pub struct CompositionInstance(U, V); -impl WeakFunctor for CompositionInstance { - type F<'a, A: 'a> = U::F<'a, V::F<'a, A>> where Self: 'a; +impl<'a, U: WeakFunctorA<'a>, V: WeakFunctorA<'a>> WeakFunctorA<'a> for CompositionInstance { + type Fa = U::Fa>; } impl<'a, U: Functor<'a>, V: Functor<'a>> Functor<'a> for CompositionInstance { - fn fmap(f: impl 'a + FnOnce(A) -> B, fa: Self::F<'a, A>) -> Self::F<'a, B> { + fn fmap(f: impl 'a + FnOnce(A) -> B, fa: Self::Fa) -> Self::Fa { U::fmap(|ua| V::fmap(f, ua), fa) } - fn replace(fa: Self::F<'a, A>, b: B) -> Self::F<'a, B> { + fn replace(fa: Self::Fa, b: B) -> Self::Fa { U::fmap(|ua| V::replace(ua, b), fa) } - fn void(fa: Self::F<'a, A>) -> Self::F<'a, ()> { + fn void(fa: Self::Fa) -> Self::Fa<()> { U::fmap(|ua| V::void(ua), fa) } } impl<'a, U: Pure<'a>, V: Pure<'a>> Pure<'a> for CompositionInstance { - fn pure(a: A) -> Self::F<'a, A> { + fn pure(a: A) -> Self::Fa { U::pure(V::pure(a)) } } @@ -29,10 +29,7 @@ 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<'a, impl 'a + FnOnce(A) -> B>, - fa: Self::F<'a, A>, - ) -> Self::F<'a, B> { + fn seq(ff: Self::Fa B>, fa: Self::Fa) -> Self::Fa { U::la2(|uf, ua| V::seq(uf, ua), ff, fa) } } @@ -42,9 +39,9 @@ impl<'a, U: ApplicativeLA2<'a>, V: ApplicativeLA2<'a>> ApplicativeLA2<'a> { fn la2( f: impl 'a + FnOnce(A, B) -> C, - fa: Self::F<'a, A>, - fb: Self::F<'a, B>, - ) -> Self::F<'a, C> { + fa: Self::Fa, + fb: Self::Fa, + ) -> Self::Fa { U::la2(|ua, ub| V::la2(f, ua, ub), fa, fb) } } @@ -52,7 +49,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<'a, A>, Self::F<'a, B>)) -> Self::F<'a, (A, B)> { + fn tuple(fab: (Self::Fa, Self::Fa)) -> Self::Fa<(A, B)> { U::fmap(V::tuple, U::tuple(fab)) } } @@ -60,10 +57,7 @@ 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<'a, A>, - fb: Self::F<'a, B>, - ) -> SelectedWrapped<'a, A, B, Self> { + fn select(fa: Self::Fa, fb: Self::Fa) -> SelectedWrapped<'a, A, B, Self> { U::fmap( |selected| match selected { Selected::A(ua, fb) => V::fmap(|a| Selected::A(a, fb), ua), @@ -75,28 +69,25 @@ 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<'a, A>, fb: Self::F<'a, B>) -> Self::F<'a, B> { + fn discard_first(fa: Self::Fa, fb: Self::Fa) -> Self::Fa { U::la2(|ua, ub| V::discard_first(ua, ub), fa, fb) } - fn discard_second(fa: Self::F<'a, A>, fb: Self::F<'a, B>) -> Self::F<'a, A> { + fn discard_second(fa: Self::Fa, fb: Self::Fa) -> Self::Fa { U::la2(|ua, ub| V::discard_second(ua, ub), fa, fb) } } -impl<'a, U: Monad<'a>, V: Monad<'a> + LocalFunctor> Monad<'a> for CompositionInstance { - fn bind( - fa: Self::F<'a, A>, - f: impl 'a + FnOnce(A) -> Self::F<'a, B>, - ) -> Self::F<'a, B> { +impl<'a, U: Monad<'a>, V: Monad<'a> + LocalFunctor<'a>> Monad<'a> for CompositionInstance { + fn bind(fa: Self::Fa, f: impl 'a + FnOnce(A) -> Self::Fa) -> Self::Fa { U::bind(fa, |ua| U::fmap(V::join, V::stuff::<_, U>(V::fmap(f, ua)))) } - fn iterate(f: impl Iterative<'a, T = Self, B = B>) -> Self::F<'a, B> { + fn iterate(f: impl Iterative<'a, T = Self, B = B>) -> Self::Fa { U::iterate(ComposedIterative(f)) } - fn join(ffa: Self::F<'a, Self::F<'a, A>>) -> Self::F<'a, A> { + fn join(ffa: Self::Fa>) -> Self::Fa { U::join(U::fmap(|ufa| U::fmap(V::join, V::stuff::<_, U>(ufa)), ffa)) } } @@ -106,7 +97,7 @@ struct ComposedIterative(F); impl< 'a, U: Monad<'a>, - V: Monad<'a> + LocalFunctor, + V: Monad<'a> + LocalFunctor<'a>, F: Iterative<'a, T = CompositionInstance>, > Iterative<'a> for ComposedIterative { @@ -125,63 +116,36 @@ impl< } } -impl<'a, E: 'a, U: Monad<'a>, V: Fail<'a, E> + LocalFunctor> Fail<'a, E> +impl<'a, E: 'a, U: Monad<'a>, V: Fail<'a, E> + LocalFunctor<'a>> Fail<'a, E> for CompositionInstance { - fn fail(e: E) -> Self::F<'a, A> { + fn fail(e: E) -> Self::Fa { U::pure(V::fail(e)) } } -impl Functor<'a>, V: LocalFunctor> LocalFunctor +impl<'a, U: LocalFunctor<'a> + Functor<'a>, V: LocalFunctor<'a>> LocalFunctor<'a> for CompositionInstance { - fn unstuff<'a, A: 'a, B: 'a>( - state: Self::F<'a, ControlFlow>, - ) -> ControlFlow, A> - where - Self: 'a, - { + fn unstuff(state: Self::Fa>) -> ControlFlow, A> { U::unstuff(U::fmap(V::unstuff, state)) } - fn stuff<'a, A: 'a, T: Pure<'a>>(fa: Self::F<'a, T::F<'a, A>>) -> T::F<'a, Self::F<'a, A>> - where - Self: 'a, - { + fn stuff>(fa: Self::Fa>) -> T::Fa> { U::stuff::<_, T>(U::fmap(V::stuff::<_, T>, fa)) } } -impl Functor<'a>, V: SharedFunctor> SharedFunctor +impl<'a, U: SharedFunctorA<'a> + Functor<'a>, V: SharedFunctorA<'a>> SharedFunctorA<'a> for CompositionInstance { - type Shared<'a, A: 'a + Clone> = U::Shared<'a, V::Shared<'a, A>> - where - Self: 'a; + type SharedA = U::SharedA>; - fn share<'a, A: 'a + Clone>(fa: Self::F<'a, A>) -> Self::Shared<'a, A> - where - Self: 'a, - { + fn share(fa: Self::Fa) -> Self::SharedA { U::share(U::fmap(V::share, fa)) } - fn unshare<'a, A: 'a + Clone>(sa: Self::Shared<'a, A>) -> Self::F<'a, A> - where - Self: 'a, - { + fn unshare(sa: Self::SharedA) -> Self::Fa { U::fmap(V::unshare, U::unshare(sa)) } } - -impl Functor<'a>, V: CovariantFunctor> CovariantFunctor - for CompositionInstance -{ - fn variate<'a: 'b, 'b, A: 'a>(fa: Self::F<'a, A>) -> Self::F<'b, A> - where - Self: 'a, - { - U::fmap(V::variate, U::variate(fa)) - } -} diff --git a/src/func/instances/effect.rs b/src/func/instances/effect.rs index a5b7f72..5334b8d 100644 --- a/src/func/instances/effect.rs +++ b/src/func/instances/effect.rs @@ -23,7 +23,7 @@ impl WithEffect { } } -#[derive(SharedFunctor, CovariantFunctor)] +#[derive(SharedFunctor)] pub struct EffectInstance(E); impl WeakFunctor for EffectInstance { @@ -33,14 +33,14 @@ impl WeakFunctor for EffectInstance { } impl<'a, E: 'a> Functor<'a> for EffectInstance { - fn fmap(f: impl 'a + FnOnce(A) -> B, fa: Self::F<'a, A>) -> Self::F<'a, B> { + fn fmap(f: impl 'a + FnOnce(A) -> B, fa: Self::Fa) -> Self::Fa { WithEffect { value: f(fa.value), effect: fa.effect, } } - fn replace(fa: Self::F<'a, A>, b: B) -> Self::F<'a, B> { + fn replace(fa: Self::Fa, b: B) -> Self::Fa { drop(fa.value); WithEffect { value: b, @@ -50,7 +50,7 @@ impl<'a, E: 'a> Functor<'a> for EffectInstance { } impl<'a, E: 'a + Effect> Pure<'a> for EffectInstance { - fn pure(a: A) -> Self::F<'a, A> { + fn pure(a: A) -> Self::Fa { WithEffect { value: a, effect: E::e_pure(), @@ -59,10 +59,7 @@ impl<'a, E: 'a + Effect> Pure<'a> for EffectInstance { } impl<'a, E: 'a + Effect> ApplicativeSeq<'a> for EffectInstance { - fn seq( - ff: Self::F<'a, impl 'a + FnOnce(A) -> B>, - fa: Self::F<'a, A>, - ) -> Self::F<'a, B> + fn seq(ff: Self::Fa B>, fa: Self::Fa) -> Self::Fa where Self: 'a, { @@ -76,9 +73,9 @@ impl<'a, E: 'a + Effect> ApplicativeSeq<'a> for EffectInstance { impl<'a, E: 'a + Effect> ApplicativeLA2<'a> for EffectInstance { fn la2( f: impl 'a + FnOnce(A, B) -> C, - fa: Self::F<'a, A>, - fb: Self::F<'a, B>, - ) -> Self::F<'a, C> + fa: Self::Fa, + fb: Self::Fa, + ) -> Self::Fa where Self: 'a, { @@ -90,7 +87,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<'a, A>, Self::F<'a, B>)) -> Self::F<'a, (A, B)> { + fn tuple((fa, fb): (Self::Fa, Self::Fa)) -> Self::Fa<(A, B)> { WithEffect { value: (fa.value, fb.value), effect: E::e_seq(fa.effect, fb.effect), @@ -101,7 +98,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<'a, A>, fb: Self::F<'a, B>) -> Self::F<'a, B> { + fn discard_first(fa: Self::Fa, fb: Self::Fa) -> Self::Fa { drop(fa.value); WithEffect { value: fb.value, @@ -109,7 +106,7 @@ impl<'a, E: 'a + Effect> Applicative<'a> for EffectInstance { } } - fn discard_second(fa: Self::F<'a, A>, fb: Self::F<'a, B>) -> Self::F<'a, A> { + fn discard_second(fa: Self::Fa, fb: Self::Fa) -> Self::Fa { drop(fb.value); WithEffect { value: fa.value, @@ -119,14 +116,11 @@ impl<'a, E: 'a + Effect> Applicative<'a> for EffectInstance { } impl<'a, E: 'a + Effect> Monad<'a> for EffectInstance { - fn bind( - fa: Self::F<'a, A>, - f: impl 'a + FnOnce(A) -> Self::F<'a, B>, - ) -> Self::F<'a, B> { + fn bind(fa: Self::Fa, f: impl 'a + FnOnce(A) -> Self::Fa) -> Self::Fa { f(fa.value).e_after(fa.effect) } - fn iterate(mut f: impl Iterative<'a, T = Self, B = B>) -> Self::F<'a, B> { + fn iterate(mut f: impl Iterative<'a, T = Self, B = B>) -> Self::Fa { let mut effect = E::e_pure(); loop { let fa = f.next(); @@ -138,16 +132,13 @@ impl<'a, E: 'a + Effect> Monad<'a> for EffectInstance { } } - fn join(ffa: Self::F<'a, Self::F<'a, A>>) -> Self::F<'a, A> { + fn join(ffa: Self::Fa>) -> Self::Fa { ffa.value.e_after(ffa.effect) } } -impl LocalFunctor for EffectInstance { - fn stuff<'a, A: 'a, T: Pure<'a>>(fa: Self::F<'a, T::F<'a, A>>) -> T::F<'a, Self::F<'a, A>> - where - Self: 'a, - { +impl<'a, E: 'a> LocalFunctor<'a> for EffectInstance { + fn stuff>(fa: Self::Fa>) -> T::Fa> { T::fmap( |a| WithEffect { value: a, diff --git a/src/func/instances/future.rs b/src/func/instances/future.rs index f46ac02..e1bb221 100644 --- a/src/func/instances/future.rs +++ b/src/func/instances/future.rs @@ -12,7 +12,6 @@ use futures::{ use crate::func::*; -#[derive(CovariantFunctor)] pub struct FutureInstance; impl WeakFunctor for FutureInstance { @@ -20,11 +19,11 @@ impl WeakFunctor for FutureInstance { } impl<'a> Functor<'a> for FutureInstance { - fn fmap(f: impl 'a + FnOnce(A) -> B, fa: Self::F<'a, A>) -> Self::F<'a, B> { + fn fmap(f: impl 'a + FnOnce(A) -> B, fa: Self::Fa) -> Self::Fa { Box::pin(async { f(fa.await) }) } - fn replace(fa: Self::F<'a, A>, b: B) -> Self::F<'a, B> { + fn replace(fa: Self::Fa, b: B) -> Self::Fa { Box::pin(async { fa.await; b @@ -33,16 +32,13 @@ impl<'a> Functor<'a> for FutureInstance { } impl<'a> Pure<'a> for FutureInstance { - fn pure(a: A) -> Self::F<'a, A> { + fn pure(a: A) -> Self::Fa { Box::pin(async { a }) } } impl<'a> ApplicativeSeq<'a> for FutureInstance { - fn seq( - ff: Self::F<'a, impl 'a + FnOnce(A) -> B>, - fa: Self::F<'a, A>, - ) -> Self::F<'a, B> { + fn seq(ff: Self::Fa B>, fa: Self::Fa) -> Self::Fa { Box::pin(async { let (f, a) = join!(ff, fa); f(a) @@ -53,9 +49,9 @@ impl<'a> ApplicativeSeq<'a> for FutureInstance { impl<'a> ApplicativeLA2<'a> for FutureInstance { fn la2( f: impl 'a + FnOnce(A, B) -> C, - fa: Self::F<'a, A>, - fb: Self::F<'a, B>, - ) -> Self::F<'a, C> { + fa: Self::Fa, + fb: Self::Fa, + ) -> Self::Fa { Box::pin(async { let (a, b) = join!(fa, fb); f(a, b) @@ -64,16 +60,13 @@ impl<'a> ApplicativeLA2<'a> for FutureInstance { } impl<'a> ApplicativeTuple<'a> for FutureInstance { - fn tuple((fa, fb): (Self::F<'a, A>, Self::F<'a, B>)) -> Self::F<'a, (A, B)> { + fn tuple((fa, fb): (Self::Fa, Self::Fa)) -> Self::Fa<(A, B)> { Box::pin(async { join!(fa, fb) }) } } impl<'a> ApplicativeSelect<'a> for FutureInstance { - fn select( - fa: Self::F<'a, A>, - fb: Self::F<'a, B>, - ) -> SelectedWrapped<'a, A, B, Self> { + fn select(fa: Self::Fa, fb: Self::Fa) -> SelectedWrapped<'a, A, B, Self> { Box::pin(async { match select(fa, fb).await { Either::Left((a, fb)) => Selected::A(a, fb), @@ -84,24 +77,21 @@ impl<'a> ApplicativeSelect<'a> for FutureInstance { } impl<'a> Applicative<'a> for FutureInstance { - fn discard_first(fa: Self::F<'a, A>, fb: Self::F<'a, B>) -> Self::F<'a, B> { + fn discard_first(fa: Self::Fa, fb: Self::Fa) -> Self::Fa { Box::pin(async { join!(fa, fb).1 }) } - fn discard_second(fa: Self::F<'a, A>, fb: Self::F<'a, B>) -> Self::F<'a, A> { + fn discard_second(fa: Self::Fa, fb: Self::Fa) -> Self::Fa { Box::pin(async { join!(fa, fb).0 }) } } impl<'a> Monad<'a> for FutureInstance { - fn bind( - fa: Self::F<'a, A>, - f: impl 'a + FnOnce(A) -> Self::F<'a, B>, - ) -> Self::F<'a, B> { + fn bind(fa: Self::Fa, f: impl 'a + FnOnce(A) -> Self::Fa) -> Self::Fa { Box::pin(async { f(fa.await).await }) } - fn iterate(mut f: impl Iterative<'a, T = Self, B = B>) -> Self::F<'a, B> { + fn iterate(mut f: impl Iterative<'a, T = Self, B = B>) -> Self::Fa { Box::pin(async move { loop { match f.next().await { @@ -112,27 +102,19 @@ impl<'a> Monad<'a> for FutureInstance { }) } - fn join(ffa: Self::F<'a, Self::F<'a, A>>) -> Self::F<'a, A> { + fn join(ffa: Self::Fa>) -> Self::Fa { Box::pin(async { ffa.await.await }) } } -impl SharedFunctor for FutureInstance { - type Shared<'a, A: 'a + Clone> = Shared>>> - where - Self: 'a; +impl<'a> SharedFunctorA<'a> for FutureInstance { + type SharedA = Shared>>>; - fn share<'a, A: 'a + Clone>(fa: Self::F<'a, A>) -> Self::Shared<'a, A> - where - Self: 'a, - { + fn share(fa: Self::Fa) -> Self::SharedA { fa.shared() } - fn unshare<'a, A: 'a + Clone>(sa: Self::Shared<'a, A>) -> Self::F<'a, A> - where - Self: 'a, - { + fn unshare(sa: Self::SharedA) -> Self::Fa { Box::pin(sa) } } diff --git a/src/func/instances/lazy.rs b/src/func/instances/lazy.rs index bc561df..5927ba2 100644 --- a/src/func/instances/lazy.rs +++ b/src/func/instances/lazy.rs @@ -11,7 +11,6 @@ use std::{cell::RefCell, rc::Rc}; use crate::func::*; -#[derive(CovariantFunctor)] pub struct LazyInstance; impl WeakFunctor for LazyInstance { @@ -19,32 +18,29 @@ impl WeakFunctor for LazyInstance { } impl<'a> Functor<'a> for LazyInstance { - fn fmap(f: impl 'a + FnOnce(A) -> B, fa: Self::F<'a, A>) -> Self::F<'a, B> { + fn fmap(f: impl 'a + FnOnce(A) -> B, fa: Self::Fa) -> Self::Fa { Box::new(|| f(fa())) } - fn replace(fa: Self::F<'a, A>, b: B) -> Self::F<'a, B> { + fn replace(fa: Self::Fa, b: B) -> Self::Fa { drop(fa); Box::new(|| b) } - fn void(fa: Self::F<'a, A>) -> Self::F<'a, ()> { + fn void(fa: Self::Fa) -> Self::Fa<()> { drop(fa); Box::new(|| ()) } } impl<'a> Pure<'a> for LazyInstance { - fn pure(a: A) -> Self::F<'a, A> { + fn pure(a: A) -> Self::Fa { Box::new(|| a) } } impl<'a> ApplicativeSeq<'a> for LazyInstance { - fn seq( - ff: Self::F<'a, impl 'a + FnOnce(A) -> B>, - fa: Self::F<'a, A>, - ) -> Self::F<'a, B> { + fn seq(ff: Self::Fa B>, fa: Self::Fa) -> Self::Fa { Box::new(|| ff()(fa())) } } @@ -52,15 +48,15 @@ impl<'a> ApplicativeSeq<'a> for LazyInstance { impl<'a> ApplicativeLA2<'a> for LazyInstance { fn la2( f: impl 'a + FnOnce(A, B) -> C, - fa: Self::F<'a, A>, - fb: Self::F<'a, B>, - ) -> Self::F<'a, C> { + fa: Self::Fa, + fb: Self::Fa, + ) -> Self::Fa { Box::new(|| f(fa(), fb())) } } impl<'a> ApplicativeTuple<'a> for LazyInstance { - fn tuple((fa, fb): (Self::F<'a, A>, Self::F<'a, B>)) -> Self::F<'a, (A, B)> { + fn tuple((fa, fb): (Self::Fa, Self::Fa)) -> Self::Fa<(A, B)> { Box::new(|| (fa(), fb())) } } @@ -68,26 +64,23 @@ impl<'a> ApplicativeTuple<'a> for LazyInstance { impl<'a> ApplicativeSelect<'a> for LazyInstance {} impl<'a> Applicative<'a> for LazyInstance { - fn discard_first(fa: Self::F<'a, A>, fb: Self::F<'a, B>) -> Self::F<'a, B> { + fn discard_first(fa: Self::Fa, fb: Self::Fa) -> Self::Fa { drop(fa); fb } - fn discard_second(fa: Self::F<'a, A>, fb: Self::F<'a, B>) -> Self::F<'a, A> { + fn discard_second(fa: Self::Fa, fb: Self::Fa) -> Self::Fa { drop(fb); fa } } impl<'a> Monad<'a> for LazyInstance { - fn bind( - fa: Self::F<'a, A>, - f: impl 'a + FnOnce(A) -> Self::F<'a, B>, - ) -> Self::F<'a, B> { + fn bind(fa: Self::Fa, f: impl 'a + FnOnce(A) -> Self::Fa) -> Self::Fa { Box::new(|| f(fa())()) } - fn iterate(mut f: impl Iterative<'a, T = Self, B = B>) -> Self::F<'a, B> { + fn iterate(mut f: impl Iterative<'a, T = Self, B = B>) -> Self::Fa { loop { match f.next()() { ControlFlow::Continue(next_f) => f = next_f, @@ -96,7 +89,7 @@ impl<'a> Monad<'a> for LazyInstance { } } - fn join(ffa: Self::F<'a, Self::F<'a, A>>) -> Self::F<'a, A> { + fn join(ffa: Self::Fa>) -> Self::Fa { Box::new(|| ffa()()) } } @@ -110,22 +103,14 @@ fn unshare<'a, A: 'a + Clone>(shared: &mut Option A>>) a } -impl SharedFunctor for LazyInstance { - type Shared<'a, A: 'a + Clone> = Rc A>>>> - where - Self: 'a; +impl<'a> SharedFunctorA<'a> for LazyInstance { + type SharedA = Rc A>>>>; - fn share<'a, A: 'a + Clone>(fa: Self::F<'a, A>) -> Self::Shared<'a, A> - where - Self: 'a, - { + fn share(fa: Self::Fa) -> Self::SharedA { Rc::new(RefCell::new(Some(fa))) } - fn unshare<'a, A: 'a + Clone>(sa: Self::Shared<'a, A>) -> Self::F<'a, A> - where - Self: 'a, - { + fn unshare(sa: Self::SharedA) -> Self::Fa { Box::new(move || unshare(&mut *sa.borrow_mut())) } } diff --git a/src/func/instances/option.rs b/src/func/instances/option.rs index 1eb16e8..f455eb5 100644 --- a/src/func/instances/option.rs +++ b/src/func/instances/option.rs @@ -9,7 +9,7 @@ use crate::func::*; -#[derive(SharedFunctor, CovariantFunctor)] +#[derive(SharedFunctor)] pub struct OptionInstance; impl WeakFunctor for OptionInstance { @@ -17,32 +17,29 @@ impl WeakFunctor for OptionInstance { } impl<'a> Functor<'a> for OptionInstance { - fn fmap(f: impl 'a + FnOnce(A) -> B, fa: Self::F<'a, A>) -> Self::F<'a, B> { + fn fmap(f: impl 'a + FnOnce(A) -> B, fa: Self::Fa) -> Self::Fa { fa.map(f) } - fn replace(fa: Self::F<'a, A>, b: B) -> Self::F<'a, B> { + fn replace(fa: Self::Fa, b: B) -> Self::Fa { fa?; Self::pure(b) } - fn void(fa: Self::F<'a, A>) -> Self::F<'a, ()> { + fn void(fa: Self::Fa) -> Self::Fa<()> { fa?; Self::pure(()) } } impl<'a> Pure<'a> for OptionInstance { - fn pure(a: A) -> Self::F<'a, A> { + fn pure(a: A) -> Self::Fa { Some(a) } } impl<'a> ApplicativeSeq<'a> for OptionInstance { - fn seq( - ff: Self::F<'a, impl 'a + FnOnce(A) -> B>, - fa: Self::F<'a, A>, - ) -> Self::F<'a, B> { + fn seq(ff: Self::Fa B>, fa: Self::Fa) -> Self::Fa { Self::pure(ff?(fa?)) } } @@ -50,15 +47,15 @@ impl<'a> ApplicativeSeq<'a> for OptionInstance { impl<'a> ApplicativeLA2<'a> for OptionInstance { fn la2( f: impl 'a + FnOnce(A, B) -> C, - fa: Self::F<'a, A>, - fb: Self::F<'a, B>, - ) -> Self::F<'a, C> { + fa: Self::Fa, + fb: Self::Fa, + ) -> Self::Fa { Self::pure(f(fa?, fb?)) } } impl<'a> ApplicativeTuple<'a> for OptionInstance { - fn tuple((fa, fb): (Self::F<'a, A>, Self::F<'a, B>)) -> Self::F<'a, (A, B)> { + fn tuple((fa, fb): (Self::Fa, Self::Fa)) -> Self::Fa<(A, B)> { Self::pure((fa?, fb?)) } } @@ -66,26 +63,23 @@ impl<'a> ApplicativeTuple<'a> for OptionInstance { impl<'a> ApplicativeSelect<'a> for OptionInstance {} impl<'a> Applicative<'a> for OptionInstance { - fn discard_first(fa: Self::F<'a, A>, fb: Self::F<'a, B>) -> Self::F<'a, B> { + fn discard_first(fa: Self::Fa, fb: Self::Fa) -> Self::Fa { fa?; fb } - fn discard_second(fa: Self::F<'a, A>, fb: Self::F<'a, B>) -> Self::F<'a, A> { + fn discard_second(fa: Self::Fa, fb: Self::Fa) -> Self::Fa { fb?; fa } } impl<'a> Monad<'a> for OptionInstance { - fn bind( - fa: Self::F<'a, A>, - f: impl 'a + FnOnce(A) -> Self::F<'a, B>, - ) -> Self::F<'a, B> { + fn bind(fa: Self::Fa, f: impl 'a + FnOnce(A) -> Self::Fa) -> Self::Fa { f(fa?) } - fn iterate(mut f: impl Iterative<'a, T = Self, B = B>) -> Self::F<'a, B> { + fn iterate(mut f: impl Iterative<'a, T = Self, B = B>) -> Self::Fa { loop { match f.next()? { ControlFlow::Continue(next_f) => f = next_f, @@ -94,18 +88,13 @@ impl<'a> Monad<'a> for OptionInstance { } } - fn join(ffa: Self::F<'a, Self::F<'a, A>>) -> Self::F<'a, A> { + fn join(ffa: Self::Fa>) -> Self::Fa { ffa? } } -impl LocalFunctor for OptionInstance { - fn unstuff<'a, A: 'a, B: 'a>( - state: Self::F<'a, ControlFlow>, - ) -> ControlFlow, A> - where - Self: 'a, - { +impl<'a> LocalFunctor<'a> for OptionInstance { + fn unstuff(state: Self::Fa>) -> ControlFlow, A> { match state { Some(ControlFlow::Continue(a)) => ControlFlow::Continue(a), Some(ControlFlow::Break(b)) => ControlFlow::Break(Some(b)), @@ -113,10 +102,7 @@ impl LocalFunctor for OptionInstance { } } - fn stuff<'a, A: 'a, T: Pure<'a>>(fa: Self::F<'a, T::F<'a, A>>) -> T::F<'a, Self::F<'a, A>> - where - Self: 'a, - { + fn stuff>(fa: Self::Fa>) -> T::Fa> { match fa { Some(ua) => T::fmap(Some, ua), None => T::pure(None), @@ -125,7 +111,7 @@ impl LocalFunctor for OptionInstance { } impl<'a> Fail<'a, ()> for OptionInstance { - fn fail(_e: ()) -> Self::F<'a, A> { + fn fail(_e: ()) -> Self::Fa { None } } @@ -136,21 +122,18 @@ mod option_tests { use super::OptionInstance as T; - impl tests::Eqr for T { - fn eqr<'a, A: PartialEq + std::fmt::Debug + 'a>( + impl<'a> tests::Eqr<'a> for T { + fn eqr( name: &'a str, - left: Self::F<'a, A>, - right: Self::F<'a, A>, + left: Self::Fa, + right: Self::Fa, ) -> tests::R { tests::eqr(name, left, right) } } - impl test_suite::FunctorTestSuite for T { - fn sample<'a, A: 'a, F: FnMut(&'a dyn Fn(A) -> Self::F<'a, A>)>(mut f: F) - where - Self::F<'a, A>: 'a, - { + impl<'a> test_suite::FunctorTestSuite<'a> for T { + fn sample Self::Fa)>(mut f: F) { f(&|_| None); f(&|a| Some(a)); } diff --git a/src/func/instances/overload.rs b/src/func/instances/overload.rs index aad2743..15ccb99 100644 --- a/src/func/instances/overload.rs +++ b/src/func/instances/overload.rs @@ -12,28 +12,28 @@ pub trait DeriveApplicative {} impl DeriveApplicative for O {} pub trait DeriveMonad {} -impl WeakFunctor for OverloadInstance { - type F<'a, A: 'a> = T::F<'a, A> - where - Self: 'a; +impl<'a, T: WeakFunctorA<'a>, O: 'a + DeriveWeakFunctor> WeakFunctorA<'a> + for OverloadInstance +{ + type Fa = T::Fa; } impl<'a, T: Functor<'a>, O: 'a + DeriveFunctor> Functor<'a> for OverloadInstance { - fn fmap(f: impl 'a + FnOnce(A) -> B, fa: Self::F<'a, A>) -> Self::F<'a, B> { + fn fmap(f: impl 'a + FnOnce(A) -> B, fa: Self::Fa) -> Self::Fa { T::fmap(f, fa) } - fn replace(fa: Self::F<'a, A>, b: B) -> Self::F<'a, B> { + fn replace(fa: Self::Fa, b: B) -> Self::Fa { T::replace(fa, b) } - fn void(fa: Self::F<'a, A>) -> Self::F<'a, ()> { + fn void(fa: Self::Fa) -> Self::Fa<()> { T::void(fa) } } impl<'a, T: Pure<'a>, O: 'a + DeriveApplicative> Pure<'a> for OverloadInstance { - fn pure(a: A) -> Self::F<'a, A> { + fn pure(a: A) -> Self::Fa { T::pure(a) } } @@ -41,10 +41,7 @@ impl<'a, T: Pure<'a>, O: 'a + DeriveApplicative> Pure<'a> for OverloadInstance, O: 'a + DeriveApplicative> ApplicativeSeq<'a> for OverloadInstance { - fn seq( - ff: Self::F<'a, impl 'a + FnOnce(A) -> B>, - fa: Self::F<'a, A>, - ) -> Self::F<'a, B> { + fn seq(ff: Self::Fa B>, fa: Self::Fa) -> Self::Fa { T::seq(ff, fa) } } @@ -54,9 +51,9 @@ impl<'a, T: ApplicativeLA2<'a>, O: 'a + DeriveApplicative> ApplicativeLA2<'a> { fn la2( f: impl 'a + FnOnce(A, B) -> C, - fa: Self::F<'a, A>, - fb: Self::F<'a, B>, - ) -> Self::F<'a, C> { + fa: Self::Fa, + fb: Self::Fa, + ) -> Self::Fa { T::la2(f, fa, fb) } } @@ -64,7 +61,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<'a, A>, Self::F<'a, B>)) -> Self::F<'a, (A, B)> { + fn tuple(fab: (Self::Fa, Self::Fa)) -> Self::Fa<(A, B)> { T::tuple(fab) } } @@ -72,10 +69,7 @@ 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<'a, A>, - fb: Self::F<'a, B>, - ) -> SelectedWrapped<'a, A, B, Self> { + fn select(fa: Self::Fa, fb: Self::Fa) -> SelectedWrapped<'a, A, B, Self> { T::select_map( |selected| match selected { Selected::A(a, fb) => Selected::A(a, fb), @@ -88,11 +82,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<'a, A>, fb: Self::F<'a, B>) -> Self::F<'a, B> { + fn discard_first(fa: Self::Fa, fb: Self::Fa) -> Self::Fa { T::discard_first(fa, fb) } - fn discard_second(fa: Self::F<'a, A>, fb: Self::F<'a, B>) -> Self::F<'a, A> { + fn discard_second(fa: Self::Fa, fb: Self::Fa) -> Self::Fa { T::discard_second(fa, fb) } } @@ -124,18 +118,15 @@ 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<'a, A>, - f: impl 'a + FnOnce(A) -> Self::F<'a, B>, - ) -> Self::F<'a, B> { + fn bind(fa: Self::Fa, f: impl 'a + FnOnce(A) -> Self::Fa) -> Self::Fa { T::bind(fa, f) } - fn iterate(f: impl Iterative<'a, T = Self, B = B>) -> Self::F<'a, B> { + fn iterate(f: impl Iterative<'a, T = Self, B = B>) -> Self::Fa { T::iterate(OverloadIterative::new(f)) } - fn join(ffa: Self::F<'a, Self::F<'a, A>>) -> Self::F<'a, A> { + fn join(ffa: Self::Fa>) -> Self::Fa { T::join(ffa) } } @@ -147,7 +138,7 @@ impl DeriveMonad for DeriveFail {} impl<'a, E: 'a, Ex: 'a, T: MonadFail<'a, Result>> Fail<'a, E> for OverloadInstance> { - fn fail(e: E) -> Self::F<'a, A> { + fn fail(e: E) -> Self::Fa { T::fail(Ok(e)) } } @@ -203,33 +194,18 @@ impl<'a, Ex: 'a, Fallible: MonadFailAny<'a>> MonadFailAny<'a> for DeriveFailAny< } } -impl SharedFunctor for OverloadInstance { - type Shared<'a, A: 'a + Clone> = T::Shared<'a, A> - where - Self: 'a; +impl<'a, T: SharedFunctorA<'a>, O: 'a + DeriveWeakFunctor> SharedFunctorA<'a> + for OverloadInstance +{ + type SharedA = T::SharedA; - fn share<'a, A: 'a + Clone>(fa: Self::F<'a, A>) -> Self::Shared<'a, A> - where - Self: 'a, - { + fn share(fa: Self::Fa) -> Self::SharedA { T::share(fa) } - fn unshare<'a, A: 'a + Clone>(sa: Self::Shared<'a, A>) -> Self::F<'a, A> - where - Self: 'a, - { + fn unshare(sa: Self::SharedA) -> Self::Fa { T::unshare(sa) } } -impl CovariantFunctor for OverloadInstance { - fn variate<'a: 'b, 'b, A: 'a>(fa: Self::F<'a, A>) -> Self::F<'b, A> - where - Self: 'a, - { - T::variate(fa) - } -} - pub type EmbedFail = OverloadInstance>; diff --git a/src/func/instances/result.rs b/src/func/instances/result.rs index e1a19de..0943255 100644 --- a/src/func/instances/result.rs +++ b/src/func/instances/result.rs @@ -9,7 +9,7 @@ use crate::func::*; -#[derive(SharedFunctor, CovariantFunctor)] +#[derive(SharedFunctor)] pub struct ResultInstance(E); impl WeakFunctor for ResultInstance { @@ -17,32 +17,29 @@ impl WeakFunctor for ResultInstance { } impl<'a, E: 'a> Functor<'a> for ResultInstance { - fn fmap(f: impl 'a + FnOnce(A) -> B, fa: Self::F<'a, A>) -> Self::F<'a, B> { + fn fmap(f: impl 'a + FnOnce(A) -> B, fa: Self::Fa) -> Self::Fa { fa.map(f) } - fn replace(fa: Self::F<'a, A>, b: B) -> Self::F<'a, B> { + fn replace(fa: Self::Fa, b: B) -> Self::Fa { fa?; Self::pure(b) } - fn void(fa: Self::F<'a, A>) -> Self::F<'a, ()> { + fn void(fa: Self::Fa) -> Self::Fa<()> { fa?; Self::pure(()) } } impl<'a, E: 'a> Pure<'a> for ResultInstance { - fn pure(a: A) -> Self::F<'a, A> { + fn pure(a: A) -> Self::Fa { Ok(a) } } impl<'a, E: 'a> ApplicativeSeq<'a> for ResultInstance { - fn seq( - ff: Self::F<'a, impl 'a + FnOnce(A) -> B>, - fa: Self::F<'a, A>, - ) -> Self::F<'a, B> { + fn seq(ff: Self::Fa B>, fa: Self::Fa) -> Self::Fa { Self::pure(ff?(fa?)) } } @@ -50,15 +47,15 @@ impl<'a, E: 'a> ApplicativeSeq<'a> for ResultInstance { impl<'a, E: 'a> ApplicativeLA2<'a> for ResultInstance { fn la2( f: impl 'a + FnOnce(A, B) -> C, - fa: Self::F<'a, A>, - fb: Self::F<'a, B>, - ) -> Self::F<'a, C> { + fa: Self::Fa, + fb: Self::Fa, + ) -> Self::Fa { Self::pure(f(fa?, fb?)) } } impl<'a, E: 'a> ApplicativeTuple<'a> for ResultInstance { - fn tuple((fa, fb): (Self::F<'a, A>, Self::F<'a, B>)) -> Self::F<'a, (A, B)> { + fn tuple((fa, fb): (Self::Fa, Self::Fa)) -> Self::Fa<(A, B)> { Self::pure((fa?, fb?)) } } @@ -66,26 +63,23 @@ impl<'a, E: 'a> ApplicativeTuple<'a> for ResultInstance { impl<'a, E: 'a> ApplicativeSelect<'a> for ResultInstance {} impl<'a, E: 'a> Applicative<'a> for ResultInstance { - fn discard_first(fa: Self::F<'a, A>, fb: Self::F<'a, B>) -> Self::F<'a, B> { + fn discard_first(fa: Self::Fa, fb: Self::Fa) -> Self::Fa { fa?; fb } - fn discard_second(fa: Self::F<'a, A>, fb: Self::F<'a, B>) -> Self::F<'a, A> { + fn discard_second(fa: Self::Fa, fb: Self::Fa) -> Self::Fa { fb?; fa } } impl<'a, E: 'a> Monad<'a> for ResultInstance { - fn bind( - fa: Self::F<'a, A>, - f: impl 'a + FnOnce(A) -> Self::F<'a, B>, - ) -> Self::F<'a, B> { + fn bind(fa: Self::Fa, f: impl 'a + FnOnce(A) -> Self::Fa) -> Self::Fa { f(fa?) } - fn iterate(mut f: impl Iterative<'a, T = Self, B = B>) -> Self::F<'a, B> { + fn iterate(mut f: impl Iterative<'a, T = Self, B = B>) -> Self::Fa { loop { match f.next()? { ControlFlow::Continue(next_f) => f = next_f, @@ -94,18 +88,13 @@ impl<'a, E: 'a> Monad<'a> for ResultInstance { } } - fn join(ffa: Self::F<'a, Self::F<'a, A>>) -> Self::F<'a, A> { + fn join(ffa: Self::Fa>) -> Self::Fa { ffa? } } -impl LocalFunctor for ResultInstance { - fn unstuff<'a, A: 'a, B: 'a>( - state: Self::F<'a, ControlFlow>, - ) -> ControlFlow, A> - where - Self: 'a, - { +impl<'a, E: 'a> LocalFunctor<'a> for ResultInstance { + fn unstuff(state: Self::Fa>) -> ControlFlow, A> { match state { Ok(ControlFlow::Continue(a)) => ControlFlow::Continue(a), Ok(ControlFlow::Break(b)) => ControlFlow::Break(Ok(b)), @@ -113,10 +102,7 @@ impl LocalFunctor for ResultInstance { } } - fn stuff<'a, A: 'a, T: Pure<'a>>(fa: Self::F<'a, T::F<'a, A>>) -> T::F<'a, Self::F<'a, A>> - where - Self: 'a, - { + fn stuff>(fa: Self::Fa>) -> T::Fa> { match fa { Ok(ua) => T::fmap(Ok, ua), Err(e) => T::pure(Err(e)), @@ -125,7 +111,7 @@ impl LocalFunctor for ResultInstance { } impl<'a, E: 'a> Fail<'a, E> for ResultInstance { - fn fail(e: E) -> Self::F<'a, A> { + fn fail(e: E) -> Self::Fa { Err(e) } } diff --git a/src/func/instances/solo.rs b/src/func/instances/solo.rs index c7747f2..d52b2aa 100644 --- a/src/func/instances/solo.rs +++ b/src/func/instances/solo.rs @@ -4,7 +4,7 @@ use crate::func::*; -#[derive(SharedFunctor, CovariantFunctor)] +#[derive(SharedFunctor)] pub struct SoloInstance; impl WeakFunctor for SoloInstance { @@ -12,31 +12,28 @@ impl WeakFunctor for SoloInstance { } impl<'a> Functor<'a> for SoloInstance { - fn fmap(f: impl 'a + FnOnce(A) -> B, fa: Self::F<'a, A>) -> Self::F<'a, B> { + fn fmap(f: impl 'a + FnOnce(A) -> B, fa: Self::Fa) -> Self::Fa { f(fa) } - fn replace(fa: Self::F<'a, A>, b: B) -> Self::F<'a, B> { + fn replace(fa: Self::Fa, b: B) -> Self::Fa { drop(fa); b } - fn void(fa: Self::F<'a, A>) -> Self::F<'a, ()> { + fn void(fa: Self::Fa) -> Self::Fa<()> { drop(fa); } } impl<'a> Pure<'a> for SoloInstance { - fn pure(a: A) -> Self::F<'a, A> { + fn pure(a: A) -> Self::Fa { a } } impl<'a> ApplicativeSeq<'a> for SoloInstance { - fn seq( - ff: Self::F<'a, impl 'a + FnOnce(A) -> B>, - fa: Self::F<'a, A>, - ) -> Self::F<'a, B> { + fn seq(ff: Self::Fa B>, fa: Self::Fa) -> Self::Fa { ff(fa) } } @@ -44,15 +41,15 @@ impl<'a> ApplicativeSeq<'a> for SoloInstance { impl<'a> ApplicativeLA2<'a> for SoloInstance { fn la2( f: impl 'a + FnOnce(A, B) -> C, - fa: Self::F<'a, A>, - fb: Self::F<'a, B>, - ) -> Self::F<'a, C> { + fa: Self::Fa, + fb: Self::Fa, + ) -> Self::Fa { f(fa, fb) } } impl<'a> ApplicativeTuple<'a> for SoloInstance { - fn tuple((fa, fb): (Self::F<'a, A>, Self::F<'a, B>)) -> Self::F<'a, (A, B)> { + fn tuple((fa, fb): (Self::Fa, Self::Fa)) -> Self::Fa<(A, B)> { (fa, fb) } } @@ -60,26 +57,23 @@ impl<'a> ApplicativeTuple<'a> for SoloInstance { impl<'a> ApplicativeSelect<'a> for SoloInstance {} impl<'a> Applicative<'a> for SoloInstance { - fn discard_first(fa: Self::F<'a, A>, fb: Self::F<'a, B>) -> Self::F<'a, B> { + fn discard_first(fa: Self::Fa, fb: Self::Fa) -> Self::Fa { drop(fa); fb } - fn discard_second(fa: Self::F<'a, A>, fb: Self::F<'a, B>) -> Self::F<'a, A> { + fn discard_second(fa: Self::Fa, fb: Self::Fa) -> Self::Fa { drop(fb); fa } } impl<'a> Monad<'a> for SoloInstance { - fn bind( - fa: Self::F<'a, A>, - f: impl 'a + FnOnce(A) -> Self::F<'a, B>, - ) -> Self::F<'a, B> { + fn bind(fa: Self::Fa, f: impl 'a + FnOnce(A) -> Self::Fa) -> Self::Fa { f(fa) } - fn iterate(mut f: impl Iterative<'a, T = Self, B = B>) -> Self::F<'a, B> { + fn iterate(mut f: impl Iterative<'a, T = Self, B = B>) -> Self::Fa { loop { match f.next() { ControlFlow::Continue(next_f) => f = next_f, @@ -88,31 +82,23 @@ impl<'a> Monad<'a> for SoloInstance { } } - fn join(ffa: Self::F<'a, Self::F<'a, A>>) -> Self::F<'a, A> { + fn join(ffa: Self::Fa>) -> Self::Fa { ffa } } -impl LocalFunctor for SoloInstance { - fn unstuff<'a, A: 'a, B: 'a>( - state: Self::F<'a, ControlFlow>, - ) -> ControlFlow, A> - where - Self: 'a, - { +impl<'a> LocalFunctor<'a> for SoloInstance { + fn unstuff(state: Self::Fa>) -> ControlFlow, A> { state } - fn stuff<'a, A: 'a, T: Pure<'a>>(fa: Self::F<'a, T::F<'a, A>>) -> T::F<'a, Self::F<'a, A>> - where - Self: 'a, - { + fn stuff>(fa: Self::Fa>) -> T::Fa> { fa } } impl<'a> Fail<'a, std::convert::Infallible> for SoloInstance { - fn fail(e: std::convert::Infallible) -> Self::F<'a, A> { + fn fail(e: std::convert::Infallible) -> Self::Fa { match e {} } } diff --git a/src/func/instances/stackless.rs b/src/func/instances/stackless.rs index c1cc2f3..4690d7e 100644 --- a/src/func/instances/stackless.rs +++ b/src/func/instances/stackless.rs @@ -124,11 +124,11 @@ impl WeakFunctor for StacklessInstance { } impl<'a> Functor<'a> for StacklessInstance { - fn fmap(f: impl 'a + FnOnce(A) -> B, fa: Self::F<'a, A>) -> Self::F<'a, B> { + fn fmap(f: impl 'a + FnOnce(A) -> B, fa: Self::Fa) -> Self::Fa { fa.map(f) } - fn replace(fa: Self::F<'a, A>, b: B) -> Self::F<'a, B> { + fn replace(fa: Self::Fa, b: B) -> Self::Fa { Stackless(Box::new(|takesb| { Some(EvalTree::Composite( Box::new(EvalTree::Atom(Box::new(move || fa.call(drop)))), @@ -142,16 +142,13 @@ impl<'a> Functor<'a> for StacklessInstance { } impl<'a> Pure<'a> for StacklessInstance { - fn pure(a: A) -> Self::F<'a, A> { + fn pure(a: A) -> Self::Fa { Stackless::from(a) } } impl<'a> ApplicativeSeq<'a> for StacklessInstance { - fn seq( - ff: Self::F<'a, impl 'a + FnOnce(A) -> B>, - fa: Self::F<'a, A>, - ) -> Self::F<'a, B> { + fn seq(ff: Self::Fa B>, fa: Self::Fa) -> Self::Fa { ff.bind(|f| fa.map(f)) } } @@ -159,15 +156,15 @@ impl<'a> ApplicativeSeq<'a> for StacklessInstance { impl<'a> ApplicativeLA2<'a> for StacklessInstance { fn la2( f: impl 'a + FnOnce(A, B) -> C, - fa: Self::F<'a, A>, - fb: Self::F<'a, B>, - ) -> Self::F<'a, C> { + fa: Self::Fa, + fb: Self::Fa, + ) -> Self::Fa { Self::_la2_via_seq(f, fa, fb) } } impl<'a> ApplicativeTuple<'a> for StacklessInstance { - fn tuple((fa, fb): (Self::F<'a, A>, Self::F<'a, B>)) -> Self::F<'a, (A, B)> { + fn tuple((fa, fb): (Self::Fa, Self::Fa)) -> Self::Fa<(A, B)> { Self::_tuple_via_la2((fa, fb)) } } @@ -175,7 +172,7 @@ impl<'a> ApplicativeTuple<'a> for StacklessInstance { impl<'a> ApplicativeSelect<'a> for StacklessInstance {} impl<'a> Applicative<'a> for StacklessInstance { - fn discard_first(fa: Self::F<'a, A>, fb: Self::F<'a, B>) -> Self::F<'a, B> { + fn discard_first(fa: Self::Fa, fb: Self::Fa) -> Self::Fa { Stackless(Box::new(|takesb| { Some(EvalTree::Composite( Box::new(EvalTree::Atom(Box::new(|| fa.call(drop)))), @@ -184,7 +181,7 @@ impl<'a> Applicative<'a> for StacklessInstance { })) } - fn discard_second(fa: Self::F<'a, A>, fb: Self::F<'a, B>) -> Self::F<'a, A> { + fn discard_second(fa: Self::Fa, fb: Self::Fa) -> Self::Fa { Stackless(Box::new(|takesa| { Some(EvalTree::Composite( Box::new(EvalTree::Atom(Box::new(|| fa.0(takesa)))), @@ -195,14 +192,11 @@ impl<'a> Applicative<'a> for StacklessInstance { } impl<'a> Monad<'a> for StacklessInstance { - fn bind( - fa: Self::F<'a, A>, - f: impl 'a + FnOnce(A) -> Self::F<'a, B>, - ) -> Self::F<'a, B> { + fn bind(fa: Self::Fa, f: impl 'a + FnOnce(A) -> Self::Fa) -> Self::Fa { fa.bind(f) } - fn iterate(f: impl Iterative<'a, T = Self, B = B>) -> Self::F<'a, B> { + fn iterate(f: impl Iterative<'a, T = Self, B = B>) -> Self::Fa { Self::pure(()).bind(move |_| { f.next().bind(|state| match state { ControlFlow::Continue(next_f) => Self::iterate(next_f), @@ -211,7 +205,7 @@ impl<'a> Monad<'a> for StacklessInstance { }) } - fn join(ffa: Self::F<'a, Self::F<'a, A>>) -> Self::F<'a, A> { + fn join(ffa: Self::Fa>) -> Self::Fa { Stackless(Box::new(|takesa| { let lcell = Rc::new(Cell::new(None)); let rcell = lcell.clone(); @@ -234,21 +228,18 @@ mod stackless_test { use super::StacklessInstance as T; - impl tests::Eqr for T { - fn eqr<'a, A: PartialEq + std::fmt::Debug + 'a>( + impl<'a> tests::Eqr<'a> for T { + fn eqr( name: &'a str, - left: Self::F<'a, A>, - right: Self::F<'a, A>, + left: Self::Fa, + right: Self::Fa, ) -> tests::R { tests::eqr(name, left.evaluate(), right.evaluate()) } } - impl test_suite::FunctorTestSuite for T { - fn sample<'a, A: 'a, F: FnMut(&'a dyn Fn(A) -> Self::F<'a, A>)>(mut f: F) - where - Self::F<'a, A>: 'a, - { + impl<'a> test_suite::FunctorTestSuite<'a> for T { + fn sample Self::Fa)>(mut f: F) { f(&|a| a.into()); } } diff --git a/src/func/instances/tryfuture.rs b/src/func/instances/tryfuture.rs index 6e10949..5d69dc0 100644 --- a/src/func/instances/tryfuture.rs +++ b/src/func/instances/tryfuture.rs @@ -7,7 +7,6 @@ use futures::{ use crate::func::*; -#[derive(CovariantFunctor)] pub struct TryFutureInstance(E); impl WeakFunctor for TryFutureInstance { @@ -15,11 +14,11 @@ impl WeakFunctor for TryFutureInstance { } impl<'a, E: 'a> Functor<'a> for TryFutureInstance { - fn fmap(f: impl 'a + FnOnce(A) -> B, fa: Self::F<'a, A>) -> Self::F<'a, B> { + fn fmap(f: impl 'a + FnOnce(A) -> B, fa: Self::Fa) -> Self::Fa { Box::pin(async { Ok(f(fa.await?)) }) } - fn replace(fa: Self::F<'a, A>, b: B) -> Self::F<'a, B> { + fn replace(fa: Self::Fa, b: B) -> Self::Fa { Box::pin(async { fa.await?; Ok(b) @@ -28,16 +27,13 @@ impl<'a, E: 'a> Functor<'a> for TryFutureInstance { } impl<'a, E: 'a> Pure<'a> for TryFutureInstance { - fn pure(a: A) -> Self::F<'a, A> { + fn pure(a: A) -> Self::Fa { Box::pin(async { Ok(a) }) } } impl<'a, E: 'a> ApplicativeSeq<'a> for TryFutureInstance { - fn seq( - ff: Self::F<'a, impl 'a + FnOnce(A) -> B>, - fa: Self::F<'a, A>, - ) -> Self::F<'a, B> { + fn seq(ff: Self::Fa B>, fa: Self::Fa) -> Self::Fa { Box::pin(async { let (f, a) = try_join!(ff, fa)?; Ok(f(a)) @@ -48,9 +44,9 @@ impl<'a, E: 'a> ApplicativeSeq<'a> for TryFutureInstance { impl<'a, E: 'a> ApplicativeLA2<'a> for TryFutureInstance { fn la2( f: impl 'a + FnOnce(A, B) -> C, - fa: Self::F<'a, A>, - fb: Self::F<'a, B>, - ) -> Self::F<'a, C> { + fa: Self::Fa, + fb: Self::Fa, + ) -> Self::Fa { Box::pin(async { let (a, b) = try_join!(fa, fb)?; Ok(f(a, b)) @@ -59,16 +55,13 @@ impl<'a, E: 'a> ApplicativeLA2<'a> for TryFutureInstance { } impl<'a, E: 'a> ApplicativeTuple<'a> for TryFutureInstance { - fn tuple((fa, fb): (Self::F<'a, A>, Self::F<'a, B>)) -> Self::F<'a, (A, B)> { + fn tuple((fa, fb): (Self::Fa, Self::Fa)) -> Self::Fa<(A, B)> { Box::pin(async { try_join!(fa, fb) }) } } impl<'a, E: 'a> ApplicativeSelect<'a> for TryFutureInstance { - fn select( - fa: Self::F<'a, A>, - fb: Self::F<'a, B>, - ) -> SelectedWrapped<'a, A, B, Self> { + fn select(fa: Self::Fa, fb: Self::Fa) -> SelectedWrapped<'a, A, B, Self> { Box::pin(async { match try_select(fa, fb).await { Ok(Either::Left((a, fb))) => Ok(Selected::A(a, fb)), @@ -81,24 +74,21 @@ impl<'a, E: 'a> ApplicativeSelect<'a> for TryFutureInstance { } impl<'a, E: 'a> Applicative<'a> for TryFutureInstance { - fn discard_first(fa: Self::F<'a, A>, fb: Self::F<'a, B>) -> Self::F<'a, B> { + fn discard_first(fa: Self::Fa, fb: Self::Fa) -> Self::Fa { Box::pin(async { Ok(try_join!(fa, fb)?.1) }) } - fn discard_second(fa: Self::F<'a, A>, fb: Self::F<'a, B>) -> Self::F<'a, A> { + fn discard_second(fa: Self::Fa, fb: Self::Fa) -> Self::Fa { Box::pin(async { Ok(try_join!(fa, fb)?.0) }) } } impl<'a, E: 'a> Monad<'a> for TryFutureInstance { - fn bind( - fa: Self::F<'a, A>, - f: impl 'a + FnOnce(A) -> Self::F<'a, B>, - ) -> Self::F<'a, B> { + fn bind(fa: Self::Fa, f: impl 'a + FnOnce(A) -> Self::Fa) -> Self::Fa { Box::pin(async { f(fa.await?).await }) } - fn iterate(mut f: impl Iterative<'a, T = Self, B = B>) -> Self::F<'a, B> { + fn iterate(mut f: impl Iterative<'a, T = Self, B = B>) -> Self::Fa { Box::pin(async move { loop { match f.next().await? { @@ -109,33 +99,25 @@ impl<'a, E: 'a> Monad<'a> for TryFutureInstance { }) } - fn join(ffa: Self::F<'a, Self::F<'a, A>>) -> Self::F<'a, A> { + fn join(ffa: Self::Fa>) -> Self::Fa { Box::pin(async { ffa.await?.await }) } } -impl SharedFunctor for TryFutureInstance { - type Shared<'a, A: 'a + Clone> = Shared>>>> - where - Self: 'a; +impl<'a, E: 'a + Clone> SharedFunctorA<'a> for TryFutureInstance { + type SharedA = Shared>>>>; - fn share<'a, A: 'a + Clone>(fa: Self::F<'a, A>) -> Self::Shared<'a, A> - where - Self: 'a, - { + fn share(fa: Self::Fa) -> Self::SharedA { fa.shared() } - fn unshare<'a, A: 'a + Clone>(sa: Self::Shared<'a, A>) -> Self::F<'a, A> - where - Self: 'a, - { + fn unshare(sa: Self::SharedA) -> Self::Fa { Box::pin(sa) } } impl<'a, E: 'a> Fail<'a, E> for TryFutureInstance { - fn fail(e: E) -> Self::F<'a, A> { + fn fail(e: E) -> Self::Fa { Box::pin(async { Err(e) }) } } diff --git a/src/func/test_suite.rs b/src/func/test_suite.rs index 3386195..fff1cde 100644 --- a/src/func/test_suite.rs +++ b/src/func/test_suite.rs @@ -1,14 +1,11 @@ use super::tests::*; use super::*; -pub trait FunctorTestSuite: WeakFunctor + Eqr { - fn sample<'a, A: 'a, F: FnMut(&'a dyn Fn(A) -> Self::F<'a, A>)>(f: F) - where - Self::F<'a, A>: 'a, - Self: 'a; +pub trait FunctorTestSuite<'a>: WeakFunctorA<'a> + Eqr<'a> { + fn sample Self::Fa)>(f: F); } -pub fn functor_follows_laws<'a, T: Functor<'a> + FunctorTestSuite>() -> R { +pub fn functor_follows_laws<'a, T: Functor<'a> + FunctorTestSuite<'a>>() -> R { let mut res = R::default(); T::sample(|pa| { res += fmap_respects_identity::(|| pa(2)); @@ -19,7 +16,7 @@ pub fn functor_follows_laws<'a, T: Functor<'a> + FunctorTestSuite>() -> R { res } -pub fn applicative_follows_laws<'a, T: Applicative<'a> + FunctorTestSuite>() -> R { +pub fn applicative_follows_laws<'a, T: Applicative<'a> + FunctorTestSuite<'a>>() -> R { let mut res = functor_follows_laws::(); T::sample(|pa| { res += seq_respects_identity::(|| pa(2)); @@ -55,7 +52,7 @@ pub fn applicative_follows_laws<'a, T: Applicative<'a> + FunctorTestSuite>() -> res } -pub fn monad_follows_laws<'a, T: Monad<'a> + FunctorTestSuite>() -> R { +pub fn monad_follows_laws<'a, T: Monad<'a> + FunctorTestSuite<'a>>() -> R { let mut res = applicative_follows_laws::(); T::sample(|pa| { res += bind_respects_left_identity::(|x| pa(x + 3), || 2); diff --git a/src/func/tests.rs b/src/func/tests.rs index ad20c79..0104874 100644 --- a/src/func/tests.rs +++ b/src/func/tests.rs @@ -26,12 +26,8 @@ impl R { } } -pub trait Eqr: WeakFunctor { - fn eqr<'a, A: PartialEq + Debug + 'a>( - name: &'a str, - left: Self::F<'a, A>, - right: Self::F<'a, A>, - ) -> R; +pub trait Eqr<'a>: WeakFunctorA<'a> { + fn eqr(name: &'a str, left: Self::Fa, right: Self::Fa) -> R; } pub fn eqr(name: &str, left: T, right: T) -> R { @@ -91,22 +87,22 @@ impl AddAssign for R { } } -pub fn fmap_respects_identity<'a, T: Functor<'a> + Eqr, A: 'a + Debug + PartialEq>( - fa0: impl Fn() -> T::F<'a, A>, +pub fn fmap_respects_identity<'a, T: Functor<'a> + Eqr<'a>, A: 'a + Debug + PartialEq>( + fa0: impl Fn() -> T::Fa, ) -> R { T::eqr("identity: fmap id == id", T::fmap(|a| a, fa0()), fa0()) } pub fn fmap_respects_composition< 'a, - T: Functor<'a> + Eqr, + T: Functor<'a> + Eqr<'a>, A: 'a, B: 'a, C: 'a + Debug + PartialEq, >( f: impl 'a + Copy + Fn(B) -> C, g: impl 'a + Copy + Fn(A) -> B, - fa0: impl Fn() -> T::F<'a, A>, + fa0: impl Fn() -> T::Fa, ) -> R { T::eqr( "composition: fmap (f . g) == fmap f . fmap g", @@ -115,8 +111,8 @@ pub fn fmap_respects_composition< ) } -pub fn seq_respects_identity<'a, T: Applicative<'a> + Eqr, A: 'a + Debug + PartialEq>( - fa0: impl Fn() -> T::F<'a, A>, +pub fn seq_respects_identity<'a, T: Applicative<'a> + Eqr<'a>, A: 'a + Debug + PartialEq>( + fa0: impl Fn() -> T::Fa, ) -> R { T::eqr( "identity: pure id <*> v = v", @@ -127,16 +123,16 @@ pub fn seq_respects_identity<'a, T: Applicative<'a> + Eqr, A: 'a + Debug + Parti pub fn seq_respects_composition< 'a, - T: Applicative<'a> + Eqr, + T: Applicative<'a> + Eqr<'a>, A: 'a, B: 'a, C: 'a + Debug + PartialEq, F: 'a + Fn(B) -> C, G: 'a + Fn(A) -> B, >( - ff0: impl Fn() -> T::F<'a, F>, - fg0: impl Fn() -> T::F<'a, G>, - fa0: impl Fn() -> T::F<'a, A>, + ff0: impl Fn() -> T::Fa, + fg0: impl Fn() -> T::Fa, + fa0: impl Fn() -> T::Fa, ) -> R { T::eqr( "composition: pure (.) <*> u <*> v <*> w = u <*> (v <*> w)", @@ -151,7 +147,7 @@ pub fn seq_respects_composition< ) } -pub fn seq_is_homomorphic<'a, T: Applicative<'a> + Eqr, A: 'a, B: 'a + Debug + PartialEq>( +pub fn seq_is_homomorphic<'a, T: Applicative<'a> + Eqr<'a>, A: 'a, B: 'a + Debug + PartialEq>( f: impl 'a + Fn(A) -> B, a0: impl Fn() -> A, ) -> R { @@ -164,12 +160,12 @@ pub fn seq_is_homomorphic<'a, T: Applicative<'a> + Eqr, A: 'a, B: 'a + Debug + P pub fn seq_respects_interchange< 'a, - T: Applicative<'a> + Eqr, + T: Applicative<'a> + Eqr<'a>, A: 'a, B: 'a + Debug + PartialEq, F: 'a + Fn(A) -> B, >( - ff0: impl Fn() -> T::F<'a, F>, + ff0: impl Fn() -> T::Fa, a0: impl 'a + Fn() -> A, ) -> R { T::eqr( @@ -181,13 +177,13 @@ pub fn seq_respects_interchange< pub fn seq_can_be_expressed_via_la2< 'a, - T: Applicative<'a> + Eqr, + T: Applicative<'a> + Eqr<'a>, A: 'a, B: 'a + Debug + PartialEq, F: 'a + Fn(A) -> B, >( - ff0: impl Fn() -> T::F<'a, F>, - fa0: impl Fn() -> T::F<'a, A>, + ff0: impl Fn() -> T::Fa, + fa0: impl Fn() -> T::Fa, ) -> R { T::eqr( "seq via la2: (<*>) = liftA2 id", @@ -198,12 +194,12 @@ pub fn seq_can_be_expressed_via_la2< pub fn fmap_can_be_expressed_via_seq< 'a, - T: Applicative<'a> + Eqr, + T: Applicative<'a> + Eqr<'a>, A: 'a, B: 'a + Debug + PartialEq, >( f: impl 'a + Copy + Fn(A) -> B, - fa0: impl Fn() -> T::F<'a, A>, + fa0: impl Fn() -> T::Fa, ) -> R { T::eqr( "fmap via seq: fmap f x = pure f <*> x", @@ -214,12 +210,12 @@ pub fn fmap_can_be_expressed_via_seq< pub fn discard_can_be_expressed_via_seq_or_la2< 'a, - T: Applicative<'a> + Eqr, + T: Applicative<'a> + Eqr<'a>, A: 'a, B: 'a + Debug + PartialEq, >( - fa0: impl 'a + Fn() -> T::F<'a, A>, - fb0: impl 'a + Fn() -> T::F<'a, B>, + fa0: impl 'a + Fn() -> T::Fa, + fb0: impl 'a + Fn() -> T::Fa, ) -> R { T::eqr( "discard via seq: u *> v = (id <$ u) <*> v", @@ -232,8 +228,8 @@ pub fn discard_can_be_expressed_via_seq_or_la2< ) } -pub fn bind_respects_left_identity<'a, T: Monad<'a> + Eqr, A: 'a, B: 'a + Debug + PartialEq>( - f: impl 'a + Fn(A) -> T::F<'a, B>, +pub fn bind_respects_left_identity<'a, T: Monad<'a> + Eqr<'a>, A: 'a, B: 'a + Debug + PartialEq>( + f: impl 'a + Fn(A) -> T::Fa, a0: impl Fn() -> A, ) -> R { T::eqr( @@ -243,8 +239,8 @@ pub fn bind_respects_left_identity<'a, T: Monad<'a> + Eqr, A: 'a, B: 'a + Debug ) } -pub fn bind_respects_right_identity<'a, T: Monad<'a> + Eqr, A: 'a + Debug + PartialEq>( - fa0: impl Fn() -> T::F<'a, A>, +pub fn bind_respects_right_identity<'a, T: Monad<'a> + Eqr<'a>, A: 'a + Debug + PartialEq>( + fa0: impl Fn() -> T::Fa, ) -> R { T::eqr( "right identity: m >>= bind = m", @@ -253,10 +249,10 @@ pub fn bind_respects_right_identity<'a, T: Monad<'a> + Eqr, A: 'a + Debug + Part ) } -pub fn bind_is_associative<'a, T: Monad<'a> + Eqr, A: 'a, B: 'a, C: 'a + Debug + PartialEq>( - f: impl 'a + Clone + Fn(B) -> T::F<'a, C>, - g: impl 'a + Clone + Fn(A) -> T::F<'a, B>, - fa0: impl 'a + Fn() -> T::F<'a, A>, +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::Fa, + g: impl 'a + Clone + Fn(A) -> T::Fa, + fa0: impl 'a + Fn() -> T::Fa, ) -> R { T::eqr( r"associativity: m >>= (\x -> k x >>= h) = (m >>= k) >>= h", @@ -267,13 +263,13 @@ pub fn bind_is_associative<'a, T: Monad<'a> + Eqr, A: 'a, B: 'a, C: 'a + Debug + pub fn seq_can_be_expressed_via_bind< 'a, - T: Monad<'a> + Eqr, + T: Monad<'a> + Eqr<'a>, A: 'a, B: 'a + Debug + PartialEq, F: 'a + Fn(A) -> B, >( - ff0: impl Fn() -> T::F<'a, F>, - fa0: impl 'a + Fn() -> T::F<'a, A>, + ff0: impl Fn() -> T::Fa, + fa0: impl 'a + Fn() -> T::Fa, ) -> R { T::eqr( r"seq via bind: m1 <*> m2 = m1 >>= (\x1 -> m2 >>= (\x2 -> pure (x1 x2)))", @@ -282,9 +278,14 @@ pub fn seq_can_be_expressed_via_bind< ) } -pub fn fmap_can_be_expressed_via_bind<'a, T: Monad<'a> + Eqr, A: 'a, B: 'a + Debug + PartialEq>( +pub fn fmap_can_be_expressed_via_bind< + 'a, + T: Monad<'a> + Eqr<'a>, + A: 'a, + B: 'a + Debug + PartialEq, +>( f: impl 'a + Copy + Fn(A) -> B, - fa0: impl 'a + Fn() -> T::F<'a, A>, + fa0: impl 'a + Fn() -> T::Fa, ) -> R { T::eqr( "fmap via bind: fmap f xs = xs >>= return . f", diff --git a/src/rcore.rs b/src/rcore.rs index cf22d11..088466e 100644 --- a/src/rcore.rs +++ b/src/rcore.rs @@ -28,15 +28,15 @@ pub use self::slice_deserializer::*; /// Basic support for tracing events across the execution. pub trait Diagnostic<'a, T: Monad<'a>> { /// Specify that the evaluation happens after a specific event. - fn after<'b, A: 'a>(fa: T::F<'a, A>, event: impl 'b + FnOnce() -> String) -> T::F<'a, A> + fn after<'b, A: 'a>(fa: T::Fa, event: impl 'b + FnOnce() -> String) -> T::Fa where 'a: 'b; /// Specify that the evaluation happens before a specific event. - fn before<'b, A: 'a>(fa: T::F<'a, A>, event: impl 'b + FnOnce() -> String) -> T::F<'a, A> + fn before<'b, A: 'a>(fa: T::Fa, event: impl 'b + FnOnce() -> String) -> T::Fa where 'a: 'b; /// Label the evaluation step as a specific named action. - fn wrapped<'b, A: 'a>(fa: T::F<'a, A>, event: impl 'b + FnOnce() -> String) -> T::F<'a, A> + fn wrapped<'b, A: 'a>(fa: T::Fa, event: impl 'b + FnOnce() -> String) -> T::Fa where 'a: 'b; } diff --git a/src/testing.rs b/src/testing.rs index 0f26705..70a9b6b 100644 --- a/src/testing.rs +++ b/src/testing.rs @@ -13,15 +13,15 @@ use crate::rstd::typeless::*; pub struct NoDiagnostic; impl<'a, T: Monad<'a>> Diagnostic<'a, T> for NoDiagnostic { - fn after<'b, A>(fa: T::F<'a, A>, _event: impl 'b + FnOnce() -> String) -> T::F<'a, A> { + fn after<'b, A>(fa: T::Fa, _event: impl 'b + FnOnce() -> String) -> T::Fa { fa } - fn before<'b, A>(fa: T::F<'a, A>, _event: impl 'b + FnOnce() -> String) -> T::F<'a, A> { + fn before<'b, A>(fa: T::Fa, _event: impl 'b + FnOnce() -> String) -> T::Fa { fa } - fn wrapped<'b, A>(fa: T::F<'a, A>, _event: impl 'b + FnOnce() -> String) -> T::F<'a, A> { + fn wrapped<'b, A>(fa: T::Fa, _event: impl 'b + FnOnce() -> String) -> T::Fa { fa } }