WeakFunctorAny

This commit is contained in:
AF 2023-05-26 11:16:34 +00:00
parent 1012f9be5e
commit 1c87e639d4
21 changed files with 293 additions and 295 deletions

View File

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

View File

@ -4,7 +4,7 @@ pub fn n_contains<'a, T: MonadFail<'a, ()>, A: 'a, D: 'a + PartialEq>(
comparator: &'a dyn Comparator<A>, comparator: &'a dyn Comparator<A>,
n_set: Rc<dyn TraversibleBinaryNode<'a, T, A, D>>, n_set: Rc<dyn TraversibleBinaryNode<'a, T, A, D>>,
key: Rc<A>, key: Rc<A>,
) -> T::Fa<()> { ) -> T::F<()> {
let (t_setl, t_setr, k_set) = n_set.split(); let (t_setl, t_setr, k_set) = n_set.split();
match comparator.pick_smaller(key.as_ref(), k_set.as_ref()) { match comparator.pick_smaller(key.as_ref(), k_set.as_ref()) {
Comparison::L => t_contains(comparator, t_setl, key), 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<A>, comparator: &'a dyn Comparator<A>,
r_set: Rc<dyn TraversibleBinaryReference<'a, T, A, D>>, r_set: Rc<dyn TraversibleBinaryReference<'a, T, A, D>>,
key: Rc<A>, key: Rc<A>,
) -> T::Fa<()> { ) -> T::F<()> {
T::bind(r_set.resolve(), |n_set| n_contains(comparator, n_set, key)) 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<A>, comparator: &'a dyn Comparator<A>,
t_set: Rc<dyn TraversibleBinaryTree<'a, T, A, D>>, t_set: Rc<dyn TraversibleBinaryTree<'a, T, A, D>>,
key: Rc<A>, key: Rc<A>,
) -> T::Fa<()> { ) -> T::F<()> {
match t_set.refer() { match t_set.refer() {
Some(r_set) => r_contains(comparator, r_set, key), Some(r_set) => r_contains(comparator, r_set, key),
None => T::fail(()), None => T::fail(()),

View File

@ -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> { 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::Fa<()> { fn on_l(self, (t_subl, t_subr, k_sub): Split<'a, T, A, D>) -> T::F<()> {
T::la2( T::la2(
and, and,
algorithms::contains::t_contains(self.comparator, self.t_superl.clone(), k_sub.clone()), 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::Fa<()> { fn on_e(self, (t_subl, t_subr, k_sub): Split<'a, T, A, D>) -> T::F<()> {
T::la2( T::la2(
and, and,
t_subset_of_t( 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::Fa<()> { fn on_r(self, (t_subl, t_subr, k_sub): Split<'a, T, A, D>) -> T::F<()> {
T::la2( T::la2(
and, and,
algorithms::contains::t_contains(self.comparator, self.t_superr.clone(), k_sub.clone()), 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::Fa<()> { fn test(self) -> T::F<()> {
let split = self.n_subset.split(); let split = self.n_subset.split();
match self match self
.comparator .comparator
@ -99,7 +99,7 @@ pub fn n_subset_of_n<'a, T: MonadFail<'a, ()>, A: 'a, D: 'a + PartialEq>(
n_superset: Rc<dyn TraversibleBinaryNode<'a, T, A, D>>, n_superset: Rc<dyn TraversibleBinaryNode<'a, T, A, D>>,
k_l: Option<Rc<A>>, k_l: Option<Rc<A>>,
k_r: Option<Rc<A>>, k_r: Option<Rc<A>>,
) -> T::Fa<()> { ) -> T::F<()> {
let (t_superl, t_superr, k_super) = n_superset.split(); let (t_superl, t_superr, k_super) = n_superset.split();
if let Some(ref a_l) = k_l { if let Some(ref a_l) = k_l {
if let Comparison::R = comparator.pick_smaller(a_l.as_ref(), k_super.as_ref()) { 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<dyn TraversibleBinaryReference<'a, T, A, D>>, r_superset: Rc<dyn TraversibleBinaryReference<'a, T, A, D>>,
k_l: Option<Rc<A>>, k_l: Option<Rc<A>>,
k_r: Option<Rc<A>>, k_r: Option<Rc<A>>,
) -> T::Fa<()> { ) -> T::F<()> {
T::join(T::la2( T::join(T::la2(
move |n_subset, n_superset| n_subset_of_n(comparator, n_subset, n_superset, k_l, k_r), move |n_subset, n_superset| n_subset_of_n(comparator, n_subset, n_superset, k_l, k_r),
r_subset.resolve(), r_subset.resolve(),
@ -144,7 +144,7 @@ pub fn t_subset_of_t<'a, T: MonadFail<'a, ()>, A, D: 'a + PartialEq>(
t_superset: Rc<dyn TraversibleBinaryTree<'a, T, A, D>>, t_superset: Rc<dyn TraversibleBinaryTree<'a, T, A, D>>,
k_l: Option<Rc<A>>, k_l: Option<Rc<A>>,
k_r: Option<Rc<A>>, k_r: Option<Rc<A>>,
) -> T::Fa<()> { ) -> T::F<()> {
match (t_subset.refer(), t_superset.refer()) { match (t_subset.refer(), t_superset.refer()) {
(None, _) => T::pure(()), (None, _) => T::pure(()),
(Some(_), None) => T::fail(()), (Some(_), None) => T::fail(()),

View File

@ -31,9 +31,9 @@ pub use self::controlflow::{Iterative, IterativeWrapped};
#[cfg(doc)] #[cfg(doc)]
use self::instances::stackless::StacklessInstance; use self::instances::stackless::StacklessInstance;
pub trait WeakFunctor { pub trait WeakFunctorAny {
/// Type of the wrapped value. /// Type of the wrapped value.
type F<'a, A: 'a>: 'a type FAny<'a, A: 'a>: 'a
where where
Self: 'a; Self: 'a;
} }
@ -41,32 +41,32 @@ pub trait WeakFunctor {
/// Part of Haskell's `Functor f` responsible for having `f a`. /// Part of Haskell's `Functor f` responsible for having `f a`.
/// ///
/// <https://hackage.haskell.org/package/base-4.18.0.0/docs/Data-Functor.html> /// <https://hackage.haskell.org/package/base-4.18.0.0/docs/Data-Functor.html>
pub trait WeakFunctorA<'a>: 'a { pub trait WeakFunctor<'a>: 'a {
type Fa<A: 'a>: 'a; type F<A: 'a>: 'a;
} }
impl<'a, T: ?Sized + 'a + WeakFunctor> WeakFunctorA<'a> for T { impl<'a, T: ?Sized + 'a + WeakFunctorAny> WeakFunctor<'a> for T {
type Fa<A: 'a> = T::F<'a, A>; type F<A: 'a> = T::FAny<'a, A>;
} }
pub type Wrap<'a, A, T> = <T as WeakFunctorA<'a>>::Fa<A>; pub type Wrap<'a, A, T> = <T as WeakFunctor<'a>>::F<A>;
/// Rust-specific implementation of [`Functor`], respecting `move` semantics. /// Rust-specific implementation of [`Functor`], respecting `move` semantics.
/// ///
/// <https://hackage.haskell.org/package/base-4.18.0.0/docs/Data-Functor.html> /// <https://hackage.haskell.org/package/base-4.18.0.0/docs/Data-Functor.html>
pub trait Functor<'a>: WeakFunctorA<'a> { pub trait Functor<'a>: WeakFunctor<'a> {
/// Equivalent or Haskell's `fmap`. /// Equivalent or Haskell's `fmap`.
/// Due to Rust limitations, it's not a `function->function` conversion. /// Due to Rust limitations, it's not a `function->function` conversion.
/// For that see [`derivations::fmap`]. /// For that see [`derivations::fmap`].
fn fmap<A: 'a, B: 'a>(f: impl 'a + FnOnce(A) -> B, fa: Self::Fa<A>) -> Self::Fa<B>; fn fmap<A: 'a, B: 'a>(f: impl 'a + FnOnce(A) -> B, fa: Self::F<A>) -> Self::F<B>;
/// Equivalent of Haskell's `$>`/`<$`. /// Equivalent of Haskell's `$>`/`<$`.
fn replace<A: 'a, B: 'a>(fa: Self::Fa<A>, b: B) -> Self::Fa<B> { fn replace<A: 'a, B: 'a>(fa: Self::F<A>, b: B) -> Self::F<B> {
Self::fmap(|_| b, fa) Self::fmap(|_| b, fa)
} }
/// Equivalent of Haskell's `void`. /// Equivalent of Haskell's `void`.
fn void<A: 'a>(fa: Self::Fa<A>) -> Self::Fa<()> { fn void<A: 'a>(fa: Self::F<A>) -> Self::F<()> {
Self::replace(fa, ()) Self::replace(fa, ())
} }
} }
@ -74,13 +74,13 @@ pub trait Functor<'a>: WeakFunctorA<'a> {
/// Part of [`Applicative`] responsible for Haskell's value lifting, `pure`. /// Part of [`Applicative`] responsible for Haskell's value lifting, `pure`.
pub trait Pure<'a>: Functor<'a> { pub trait Pure<'a>: Functor<'a> {
/// Equivalent of Haskell's `pure`/`return`. /// Equivalent of Haskell's `pure`/`return`.
fn pure<A: 'a>(a: A) -> Self::Fa<A>; fn pure<A: 'a>(a: A) -> Self::F<A>;
} }
/// Part of [`Applicative`] responsible for Haskell's sequential application `<*>`. /// Part of [`Applicative`] responsible for Haskell's sequential application `<*>`.
pub trait ApplicativeSeq<'a>: Functor<'a> { pub trait ApplicativeSeq<'a>: Functor<'a> {
/// Equivalent of Haskell's `<*>`. /// Equivalent of Haskell's `<*>`.
fn seq<A: 'a, B: 'a>(ff: Self::Fa<impl 'a + FnOnce(A) -> B>, fa: Self::Fa<A>) -> Self::Fa<B>; fn seq<A: 'a, B: 'a>(ff: Self::F<impl 'a + FnOnce(A) -> B>, fa: Self::F<A>) -> Self::F<B>;
} }
/// Part of [`Applicative`] responsible for Haskell's result combination `listA2`. /// Part of [`Applicative`] responsible for Haskell's result combination `listA2`.
@ -88,15 +88,15 @@ pub trait ApplicativeLA2<'a>: Functor<'a> {
/// Equivalent of Haskell's `listA2`. /// Equivalent of Haskell's `listA2`.
fn la2<A: 'a, B: 'a, C: 'a>( fn la2<A: 'a, B: 'a, C: 'a>(
f: impl 'a + FnOnce(A, B) -> C, f: impl 'a + FnOnce(A, B) -> C,
fa: Self::Fa<A>, fa: Self::F<A>,
fb: Self::Fa<B>, fb: Self::F<B>,
) -> Self::Fa<C>; ) -> Self::F<C>;
} }
/// Part of [`Applicative`] responsible for Rust-style result combination, specifically for tuples. /// Part of [`Applicative`] responsible for Rust-style result combination, specifically for tuples.
pub trait ApplicativeTuple<'a>: Functor<'a> { pub trait ApplicativeTuple<'a>: Functor<'a> {
/// Similar to Haskell's `listA2` but with [Iterator::collect]-ish semantics. /// Similar to Haskell's `listA2` but with [Iterator::collect]-ish semantics.
fn tuple<A: 'a, B: 'a>(fab: (Self::Fa<A>, Self::Fa<B>)) -> Self::Fa<(A, B)>; fn tuple<A: 'a, B: 'a>(fab: (Self::F<A>, Self::F<B>)) -> Self::F<(A, B)>;
} }
/// Equivalent of Haskell's `Applicative`. /// Equivalent of Haskell's `Applicative`.
@ -107,12 +107,12 @@ pub trait Applicative<'a>:
Pure<'a> + ApplicativeSeq<'a> + ApplicativeLA2<'a> + ApplicativeTuple<'a> + ApplicativeSelect<'a> Pure<'a> + ApplicativeSeq<'a> + ApplicativeLA2<'a> + ApplicativeTuple<'a> + ApplicativeSelect<'a>
{ {
/// Equivalent of Haskell's `*>`/`>>`. /// Equivalent of Haskell's `*>`/`>>`.
fn discard_first<A: 'a, B: 'a>(fa: Self::Fa<A>, fb: Self::Fa<B>) -> Self::Fa<B> { fn discard_first<A: 'a, B: 'a>(fa: Self::F<A>, fb: Self::F<B>) -> Self::F<B> {
Self::seq(Self::replace(fa, |b| b), fb) Self::seq(Self::replace(fa, |b| b), fb)
} }
/// Equivalent of Haskell's `<*`. /// Equivalent of Haskell's `<*`.
fn discard_second<A: 'a, B: 'a>(fa: Self::Fa<A>, fb: Self::Fa<B>) -> Self::Fa<A> { fn discard_second<A: 'a, B: 'a>(fa: Self::F<A>, fb: Self::F<B>) -> Self::F<A> {
Self::la2(|a, _| a, fa, fb) Self::la2(|a, _| a, fa, fb)
} }
} }
@ -124,16 +124,16 @@ pub trait Monad<'a>: Applicative<'a> {
/// Equivalent of Haskell's `>==`. /// Equivalent of Haskell's `>==`.
/// Due to Rust limitations, it's not a `function->function` conversion. /// Due to Rust limitations, it's not a `function->function` conversion.
/// For that see [`derivations::bind`]. /// For that see [`derivations::bind`].
fn bind<A: 'a, B: 'a>(fa: Self::Fa<A>, f: impl 'a + FnOnce(A) -> Self::Fa<B>) -> Self::Fa<B>; fn bind<A: 'a, B: 'a>(fa: Self::F<A>, f: impl 'a + FnOnce(A) -> Self::F<B>) -> Self::F<B>;
/// Included for optimisation and clarity. /// Included for optimisation and clarity.
/// Generally, [`Monad::bind`] should be enough implement it. /// Generally, [`Monad::bind`] should be enough implement it.
/// See [`StacklessInstance::iterate`] for a generic, though less-than ideal, blanket implementation. /// 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. /// On practice, you generally shouldn't be using [`Monad::bind`]/[`Pure::pure`]/[`Functor::fmap`] here.
fn iterate<B: 'a>(f: impl Iterative<'a, T = Self, B = B>) -> Self::Fa<B>; fn iterate<B: 'a>(f: impl Iterative<'a, T = Self, B = B>) -> Self::F<B>;
/// Equivalent of Haskell's `join`. /// Equivalent of Haskell's `join`.
fn join<A: 'a>(ffa: Self::Fa<Self::Fa<A>>) -> Self::Fa<A> { fn join<A: 'a>(ffa: Self::F<Self::F<A>>) -> Self::F<A> {
Self::bind(ffa, |fa| fa) Self::bind(ffa, |fa| fa)
} }
} }
@ -145,8 +145,8 @@ pub trait MonadExt<'a>: Monad<'a> {
/// rather than some dedicated state type. /// rather than some dedicated state type.
fn iterate_mut<A: 'a, B: 'a>( fn iterate_mut<A: 'a, B: 'a>(
a: A, a: A,
f: impl 'a + FnMut(A) -> Self::Fa<ControlFlow<B, A>>, f: impl 'a + FnMut(A) -> Self::F<ControlFlow<B, A>>,
) -> Self::Fa<B> { ) -> Self::F<B> {
Self::iterate(BindableMut::new(a, f)) Self::iterate(BindableMut::new(a, f))
} }
} }
@ -154,9 +154,9 @@ pub trait MonadExt<'a>: Monad<'a> {
impl<'a, T: Monad<'a>> MonadExt<'a> for T {} impl<'a, T: Monad<'a>> MonadExt<'a> for T {}
/// Part of [`MonadFail`] responsible for Haskell's `fail`. /// Part of [`MonadFail`] responsible for Haskell's `fail`.
pub trait Fail<'a, E: 'a>: WeakFunctorA<'a> { pub trait Fail<'a, E: 'a>: WeakFunctor<'a> {
/// Equivalent of Haskell's `fail`. /// Equivalent of Haskell's `fail`.
fn fail<A: 'a>(e: E) -> Self::Fa<A>; fn fail<A: 'a>(e: E) -> Self::F<A>;
} }
/// Equivalent of Haskell's `MonadFail`. Auto-implemented for all [`Fail`]`+`[`Monad`]. /// Equivalent of Haskell's `MonadFail`. Auto-implemented for all [`Fail`]`+`[`Monad`].
@ -167,14 +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 {} impl<'a, E: 'a, T: Monad<'a> + Fail<'a, E>> MonadFail<'a, E> for T {}
/// Represents wrapped results which are instantly available. /// Represents wrapped results which are instantly available.
pub trait LocalFunctor<'a>: WeakFunctorA<'a> { pub trait LocalFunctor<'a>: WeakFunctor<'a> {
/// Extract iteration state, if successful. /// Extract iteration state, if successful.
fn unstuff<A: 'a, B: 'a>(state: Self::Fa<ControlFlow<B, A>>) -> ControlFlow<Self::Fa<B>, A> { fn unstuff<A: 'a, B: 'a>(state: Self::F<ControlFlow<B, A>>) -> ControlFlow<Self::F<B>, A> {
Self::stuff::<_, ControlFlowInstance<A>>(state) Self::stuff::<_, ControlFlowInstance<A>>(state)
} }
/// Stuff wrapped result into another functor. /// Stuff wrapped result into another functor.
fn stuff<A: 'a, T: Pure<'a>>(fa: Self::Fa<T::Fa<A>>) -> T::Fa<Self::Fa<A>>; fn stuff<A: 'a, T: Pure<'a>>(fa: Self::F<T::F<A>>) -> T::F<Self::F<A>>;
} }
/// Represents a (collection of) [Monad]\(s) that can hold any type of error. /// Represents a (collection of) [Monad]\(s) that can hold any type of error.
@ -268,36 +268,36 @@ pub trait MonadFailAnyExt<'a>: MonadFailAny<'a> {
impl<'a, Fallible: ?Sized + MonadFailAny<'a>> MonadFailAnyExt<'a> for Fallible {} impl<'a, Fallible: ?Sized + MonadFailAny<'a>> MonadFailAnyExt<'a> for Fallible {}
pub trait SharedFunctorAny: WeakFunctor { pub trait SharedFunctorAny: WeakFunctorAny {
type SharedAny<'a, A: 'a + Clone>: 'a + Clone type SharedAny<'a, A: 'a + Clone>: 'a + Clone
where where
Self: 'a; Self: 'a;
fn share<'a, A: 'a + Clone>(fa: Self::F<'a, A>) -> Self::SharedAny<'a, A> fn share<'a, A: 'a + Clone>(fa: Self::FAny<'a, A>) -> Self::SharedAny<'a, A>
where where
Self: 'a; Self: 'a;
fn unshare<'a, A: 'a + Clone>(sa: Self::SharedAny<'a, A>) -> Self::F<'a, A> fn unshare<'a, A: 'a + Clone>(sa: Self::SharedAny<'a, A>) -> Self::FAny<'a, A>
where where
Self: 'a; Self: 'a;
} }
pub trait SharedFunctor<'a>: WeakFunctorA<'a> { pub trait SharedFunctor<'a>: WeakFunctor<'a> {
type Shared<A: 'a + Clone>: 'a + Clone; type Shared<A: 'a + Clone>: 'a + Clone;
fn share<A: 'a + Clone>(fa: Self::Fa<A>) -> Self::Shared<A>; fn share<A: 'a + Clone>(fa: Self::F<A>) -> Self::Shared<A>;
fn unshare<A: 'a + Clone>(sa: Self::Shared<A>) -> Self::Fa<A>; fn unshare<A: 'a + Clone>(sa: Self::Shared<A>) -> Self::F<A>;
} }
impl<'a, T: 'a + SharedFunctorAny> SharedFunctor<'a> for T { impl<'a, T: 'a + SharedFunctorAny> SharedFunctor<'a> for T {
type Shared<A: 'a + Clone> = T::SharedAny<'a, A>; type Shared<A: 'a + Clone> = T::SharedAny<'a, A>;
fn share<A: 'a + Clone>(fa: Self::Fa<A>) -> Self::Shared<A> { fn share<A: 'a + Clone>(fa: Self::F<A>) -> Self::Shared<A> {
T::share(fa) T::share(fa)
} }
fn unshare<A: 'a + Clone>(sa: Self::Shared<A>) -> Self::Fa<A> { fn unshare<A: 'a + Clone>(sa: Self::Shared<A>) -> Self::F<A> {
T::unshare(sa) T::unshare(sa)
} }
} }

View File

@ -1,14 +1,14 @@
use super::*; use super::*;
pub enum Selected<'a, A: 'a, B: 'a, T: ?Sized + WeakFunctorA<'a>> { pub enum Selected<'a, A: 'a, B: 'a, T: ?Sized + WeakFunctor<'a>> {
A(A, T::Fa<B>), A(A, T::F<B>),
B(T::Fa<A>, B), B(T::F<A>, B),
} }
pub type SelectedWrapped<'a, A, B, T> = Wrap<'a, Selected<'a, A, B, T>, T>; pub type SelectedWrapped<'a, A, B, T> = Wrap<'a, Selected<'a, A, B, T>, T>;
pub trait ApplicativeSelect<'a>: Functor<'a> { pub trait ApplicativeSelect<'a>: Functor<'a> {
fn select<A: 'a, B: 'a>(fa: Self::Fa<A>, fb: Self::Fa<B>) -> SelectedWrapped<'a, A, B, Self> { fn select<A: 'a, B: 'a>(fa: Self::F<A>, fb: Self::F<B>) -> SelectedWrapped<'a, A, B, Self> {
Self::fmap(|a| Selected::A(a, fb), fa) Self::fmap(|a| Selected::A(a, fb), fa)
} }
} }
@ -16,9 +16,9 @@ pub trait ApplicativeSelect<'a>: Functor<'a> {
pub trait ApplicativeSelectExt<'a>: ApplicativeSelect<'a> { pub trait ApplicativeSelectExt<'a>: ApplicativeSelect<'a> {
fn select_map<A: 'a, B: 'a, C: 'a>( fn select_map<A: 'a, B: 'a, C: 'a>(
f: impl 'a + FnOnce(Selected<'a, A, B, Self>) -> C, f: impl 'a + FnOnce(Selected<'a, A, B, Self>) -> C,
fa: Self::Fa<A>, fa: Self::F<A>,
fb: Self::Fa<B>, fb: Self::F<B>,
) -> Self::Fa<C> { ) -> Self::F<C> {
Self::fmap(f, Self::select(fa, fb)) Self::fmap(f, Self::select(fa, fb))
} }
} }

View File

@ -4,14 +4,14 @@ use super::*;
pub struct ControlFlowInstance<C>(ControlFlow<(), C>); pub struct ControlFlowInstance<C>(ControlFlow<(), C>);
impl<C> WeakFunctor for ControlFlowInstance<C> { impl<C> WeakFunctorAny for ControlFlowInstance<C> {
type F<'a, A: 'a> = ControlFlow<A, C> type FAny<'a, A: 'a> = ControlFlow<A, C>
where where
Self: 'a; Self: 'a;
} }
impl<'a, C: 'a> Functor<'a> for ControlFlowInstance<C> { impl<'a, C: 'a> Functor<'a> for ControlFlowInstance<C> {
fn fmap<A: 'a, B: 'a>(f: impl 'a + FnOnce(A) -> B, fa: Self::Fa<A>) -> Self::Fa<B> { fn fmap<A: 'a, B: 'a>(f: impl 'a + FnOnce(A) -> B, fa: Self::F<A>) -> Self::F<B> {
match fa { match fa {
ControlFlow::Continue(c) => ControlFlow::Continue(c), ControlFlow::Continue(c) => ControlFlow::Continue(c),
ControlFlow::Break(a) => ControlFlow::Break(f(a)), ControlFlow::Break(a) => ControlFlow::Break(f(a)),
@ -20,14 +20,14 @@ impl<'a, C: 'a> Functor<'a> for ControlFlowInstance<C> {
} }
impl<'a, C: 'a> Pure<'a> for ControlFlowInstance<C> { impl<'a, C: 'a> Pure<'a> for ControlFlowInstance<C> {
fn pure<A: 'a>(a: A) -> Self::Fa<A> { fn pure<A: 'a>(a: A) -> Self::F<A> {
ControlFlow::Break(a) ControlFlow::Break(a)
} }
} }
pub struct BindableMut<T: ?Sized, A, B, F>(A, F, PhantomData<B>, PhantomData<T>); pub struct BindableMut<T: ?Sized, A, B, F>(A, F, PhantomData<B>, PhantomData<T>);
impl<'a, T: ?Sized + Functor<'a>, A: 'a, B: 'a, F: 'a + FnMut(A) -> T::Fa<ControlFlow<B, A>>> impl<'a, T: ?Sized + Functor<'a>, A: 'a, B: 'a, F: 'a + FnMut(A) -> T::F<ControlFlow<B, A>>>
BindableMut<T, A, B, F> BindableMut<T, A, B, F>
{ {
pub fn new(a: A, f: F) -> Self { pub fn new(a: A, f: F) -> Self {
@ -35,7 +35,7 @@ impl<'a, T: ?Sized + Functor<'a>, A: 'a, B: 'a, F: 'a + FnMut(A) -> T::Fa<Contro
} }
} }
impl<'a, T: ?Sized + Functor<'a>, A: 'a, B: 'a, F: 'a + FnMut(A) -> T::Fa<ControlFlow<B, A>>> impl<'a, T: ?Sized + Functor<'a>, A: 'a, B: 'a, F: 'a + FnMut(A) -> T::F<ControlFlow<B, A>>>
Iterative<'a> for BindableMut<T, A, B, F> Iterative<'a> for BindableMut<T, A, B, F>
{ {
type B = B; type B = B;
@ -64,7 +64,7 @@ pub trait Iterative<'a>: 'a + Sized {
/// [`ControlFlow::Break`]. /// [`ControlFlow::Break`].
type B: 'a; type B: 'a;
/// Corresponding [`WeakFunctor`]. /// Corresponding [`WeakFunctor`].
type T: ?Sized + WeakFunctorA<'a>; type T: ?Sized + WeakFunctor<'a>;
/// Get next state. /// Get next state.
fn next(self) -> IterativeWrapped<'a, Self>; fn next(self) -> IterativeWrapped<'a, Self>;
} }

View File

@ -11,7 +11,7 @@ pub fn fmap<'a, T: Functor<'a>, A: 'a, B: 'a>(
/// Equivalent of Haskell's `fmap`. `function-function` equivalent of [Monad::bind]. /// Equivalent of Haskell's `fmap`. `function-function` equivalent of [Monad::bind].
pub fn bind<'a, T: Monad<'a>, A: 'a, B: 'a>( pub fn bind<'a, T: Monad<'a>, A: 'a, B: 'a>(
f: impl 'a + FnOnce(A) -> T::Fa<B>, f: impl 'a + FnOnce(A) -> T::F<B>,
) -> impl FnOnce(Wrap<'a, A, T>) -> Wrap<'a, B, T> { ) -> impl FnOnce(Wrap<'a, A, T>) -> Wrap<'a, B, T> {
move |fa| T::bind(fa, f) move |fa| T::bind(fa, f)
} }
@ -19,9 +19,9 @@ pub fn bind<'a, T: Monad<'a>, A: 'a, B: 'a>(
pub trait ApplicativeLA2ViaSeq<'a>: ApplicativeSeq<'a> { pub trait ApplicativeLA2ViaSeq<'a>: ApplicativeSeq<'a> {
fn _la2_via_seq<A: 'a, B: 'a, C: 'a>( fn _la2_via_seq<A: 'a, B: 'a, C: 'a>(
f: impl 'a + FnOnce(A, B) -> C, f: impl 'a + FnOnce(A, B) -> C,
fa: Self::Fa<A>, fa: Self::F<A>,
fb: Self::Fa<B>, fb: Self::F<B>,
) -> Self::Fa<C> { ) -> Self::F<C> {
Self::seq(Self::fmap(|a| |b| f(a, b), fa), fb) 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> { pub trait ApplicativeSeqViaLA2<'a>: ApplicativeLA2<'a> {
fn _seq_via_la2<A: 'a, B: 'a>( fn _seq_via_la2<A: 'a, B: 'a>(
ff: Self::Fa<impl 'a + FnOnce(A) -> B>, ff: Self::F<impl 'a + FnOnce(A) -> B>,
fa: Self::Fa<A>, fa: Self::F<A>,
) -> Self::Fa<B> { ) -> Self::F<B> {
Self::la2(|f, a| f(a), ff, fa) Self::la2(|f, a| f(a), ff, fa)
} }
} }
@ -40,7 +40,7 @@ pub trait ApplicativeSeqViaLA2<'a>: ApplicativeLA2<'a> {
impl<'a, T: ApplicativeLA2<'a>> ApplicativeSeqViaLA2<'a> for T {} impl<'a, T: ApplicativeLA2<'a>> ApplicativeSeqViaLA2<'a> for T {}
pub trait ApplicativeTupleViaLA2<'a>: ApplicativeLA2<'a> { pub trait ApplicativeTupleViaLA2<'a>: ApplicativeLA2<'a> {
fn _tuple_via_la2<A: 'a, B: 'a>((fa, fb): (Self::Fa<A>, Self::Fa<B>)) -> Self::Fa<(A, B)> { fn _tuple_via_la2<A: 'a, B: 'a>((fa, fb): (Self::F<A>, Self::F<B>)) -> Self::F<(A, B)> {
Self::la2(|a, b| (a, b), fa, fb) Self::la2(|a, b| (a, b), fa, fb)
} }
} }

View File

@ -2,26 +2,26 @@ use crate::func::*;
pub struct CompositionInstance<U, V>(U, V); pub struct CompositionInstance<U, V>(U, V);
impl<'a, U: WeakFunctorA<'a>, V: WeakFunctorA<'a>> WeakFunctorA<'a> for CompositionInstance<U, V> { impl<'a, U: WeakFunctor<'a>, V: WeakFunctor<'a>> WeakFunctor<'a> for CompositionInstance<U, V> {
type Fa<A: 'a> = U::Fa<V::Fa<A>>; type F<A: 'a> = U::F<V::F<A>>;
} }
impl<'a, U: Functor<'a>, V: Functor<'a>> Functor<'a> for CompositionInstance<U, V> { impl<'a, U: Functor<'a>, V: Functor<'a>> Functor<'a> for CompositionInstance<U, V> {
fn fmap<A: 'a, B: 'a>(f: impl 'a + FnOnce(A) -> B, fa: Self::Fa<A>) -> Self::Fa<B> { fn fmap<A: 'a, B: 'a>(f: impl 'a + FnOnce(A) -> B, fa: Self::F<A>) -> Self::F<B> {
U::fmap(|ua| V::fmap(f, ua), fa) U::fmap(|ua| V::fmap(f, ua), fa)
} }
fn replace<A: 'a, B: 'a>(fa: Self::Fa<A>, b: B) -> Self::Fa<B> { fn replace<A: 'a, B: 'a>(fa: Self::F<A>, b: B) -> Self::F<B> {
U::fmap(|ua| V::replace(ua, b), fa) U::fmap(|ua| V::replace(ua, b), fa)
} }
fn void<A: 'a>(fa: Self::Fa<A>) -> Self::Fa<()> { fn void<A: 'a>(fa: Self::F<A>) -> Self::F<()> {
U::fmap(|ua| V::void(ua), fa) U::fmap(|ua| V::void(ua), fa)
} }
} }
impl<'a, U: Pure<'a>, V: Pure<'a>> Pure<'a> for CompositionInstance<U, V> { impl<'a, U: Pure<'a>, V: Pure<'a>> Pure<'a> for CompositionInstance<U, V> {
fn pure<A: 'a>(a: A) -> Self::Fa<A> { fn pure<A: 'a>(a: A) -> Self::F<A> {
U::pure(V::pure(a)) U::pure(V::pure(a))
} }
} }
@ -29,7 +29,7 @@ impl<'a, U: Pure<'a>, V: Pure<'a>> Pure<'a> for CompositionInstance<U, V> {
impl<'a, U: ApplicativeLA2<'a>, V: ApplicativeSeq<'a>> ApplicativeSeq<'a> impl<'a, U: ApplicativeLA2<'a>, V: ApplicativeSeq<'a>> ApplicativeSeq<'a>
for CompositionInstance<U, V> for CompositionInstance<U, V>
{ {
fn seq<A: 'a, B: 'a>(ff: Self::Fa<impl 'a + FnOnce(A) -> B>, fa: Self::Fa<A>) -> Self::Fa<B> { fn seq<A: 'a, B: 'a>(ff: Self::F<impl 'a + FnOnce(A) -> B>, fa: Self::F<A>) -> Self::F<B> {
U::la2(|uf, ua| V::seq(uf, ua), ff, fa) U::la2(|uf, ua| V::seq(uf, ua), ff, fa)
} }
} }
@ -39,9 +39,9 @@ impl<'a, U: ApplicativeLA2<'a>, V: ApplicativeLA2<'a>> ApplicativeLA2<'a>
{ {
fn la2<A: 'a, B: 'a, C: 'a>( fn la2<A: 'a, B: 'a, C: 'a>(
f: impl 'a + FnOnce(A, B) -> C, f: impl 'a + FnOnce(A, B) -> C,
fa: Self::Fa<A>, fa: Self::F<A>,
fb: Self::Fa<B>, fb: Self::F<B>,
) -> Self::Fa<C> { ) -> Self::F<C> {
U::la2(|ua, ub| V::la2(f, ua, ub), fa, fb) U::la2(|ua, ub| V::la2(f, ua, ub), fa, fb)
} }
} }
@ -49,7 +49,7 @@ impl<'a, U: ApplicativeLA2<'a>, V: ApplicativeLA2<'a>> ApplicativeLA2<'a>
impl<'a, U: ApplicativeTuple<'a>, V: ApplicativeTuple<'a>> ApplicativeTuple<'a> impl<'a, U: ApplicativeTuple<'a>, V: ApplicativeTuple<'a>> ApplicativeTuple<'a>
for CompositionInstance<U, V> for CompositionInstance<U, V>
{ {
fn tuple<A: 'a, B: 'a>(fab: (Self::Fa<A>, Self::Fa<B>)) -> Self::Fa<(A, B)> { fn tuple<A: 'a, B: 'a>(fab: (Self::F<A>, Self::F<B>)) -> Self::F<(A, B)> {
U::fmap(V::tuple, U::tuple(fab)) U::fmap(V::tuple, U::tuple(fab))
} }
} }
@ -57,7 +57,7 @@ impl<'a, U: ApplicativeTuple<'a>, V: ApplicativeTuple<'a>> ApplicativeTuple<'a>
impl<'a, U: ApplicativeSelect<'a>, V: Functor<'a>> ApplicativeSelect<'a> impl<'a, U: ApplicativeSelect<'a>, V: Functor<'a>> ApplicativeSelect<'a>
for CompositionInstance<U, V> for CompositionInstance<U, V>
{ {
fn select<A: 'a, B: 'a>(fa: Self::Fa<A>, fb: Self::Fa<B>) -> SelectedWrapped<'a, A, B, Self> { fn select<A: 'a, B: 'a>(fa: Self::F<A>, fb: Self::F<B>) -> SelectedWrapped<'a, A, B, Self> {
U::fmap( U::fmap(
|selected| match selected { |selected| match selected {
Selected::A(ua, fb) => V::fmap(|a| Selected::A(a, fb), ua), Selected::A(ua, fb) => V::fmap(|a| Selected::A(a, fb), ua),
@ -69,25 +69,25 @@ impl<'a, U: ApplicativeSelect<'a>, V: Functor<'a>> ApplicativeSelect<'a>
} }
impl<'a, U: Applicative<'a>, V: Applicative<'a>> Applicative<'a> for CompositionInstance<U, V> { impl<'a, U: Applicative<'a>, V: Applicative<'a>> Applicative<'a> for CompositionInstance<U, V> {
fn discard_first<A: 'a, B: 'a>(fa: Self::Fa<A>, fb: Self::Fa<B>) -> Self::Fa<B> { fn discard_first<A: 'a, B: 'a>(fa: Self::F<A>, fb: Self::F<B>) -> Self::F<B> {
U::la2(|ua, ub| V::discard_first(ua, ub), fa, fb) U::la2(|ua, ub| V::discard_first(ua, ub), fa, fb)
} }
fn discard_second<A: 'a, B: 'a>(fa: Self::Fa<A>, fb: Self::Fa<B>) -> Self::Fa<A> { fn discard_second<A: 'a, B: 'a>(fa: Self::F<A>, fb: Self::F<B>) -> Self::F<A> {
U::la2(|ua, ub| V::discard_second(ua, ub), fa, fb) U::la2(|ua, ub| V::discard_second(ua, ub), fa, fb)
} }
} }
impl<'a, U: Monad<'a>, V: Monad<'a> + LocalFunctor<'a>> Monad<'a> for CompositionInstance<U, V> { impl<'a, U: Monad<'a>, V: Monad<'a> + LocalFunctor<'a>> Monad<'a> for CompositionInstance<U, V> {
fn bind<A: 'a, B: 'a>(fa: Self::Fa<A>, f: impl 'a + FnOnce(A) -> Self::Fa<B>) -> Self::Fa<B> { fn bind<A: 'a, B: 'a>(fa: Self::F<A>, f: impl 'a + FnOnce(A) -> Self::F<B>) -> Self::F<B> {
U::bind(fa, |ua| U::fmap(V::join, V::stuff::<_, U>(V::fmap(f, ua)))) U::bind(fa, |ua| U::fmap(V::join, V::stuff::<_, U>(V::fmap(f, ua))))
} }
fn iterate<B: 'a>(f: impl Iterative<'a, T = Self, B = B>) -> Self::Fa<B> { fn iterate<B: 'a>(f: impl Iterative<'a, T = Self, B = B>) -> Self::F<B> {
U::iterate(ComposedIterative(f)) U::iterate(ComposedIterative(f))
} }
fn join<A: 'a>(ffa: Self::Fa<Self::Fa<A>>) -> Self::Fa<A> { fn join<A: 'a>(ffa: Self::F<Self::F<A>>) -> Self::F<A> {
U::join(U::fmap(|ufa| U::fmap(V::join, V::stuff::<_, U>(ufa)), ffa)) U::join(U::fmap(|ufa| U::fmap(V::join, V::stuff::<_, U>(ufa)), ffa))
} }
} }
@ -119,7 +119,7 @@ impl<
impl<'a, E: 'a, U: Monad<'a>, V: Fail<'a, E> + LocalFunctor<'a>> Fail<'a, E> impl<'a, E: 'a, U: Monad<'a>, V: Fail<'a, E> + LocalFunctor<'a>> Fail<'a, E>
for CompositionInstance<U, V> for CompositionInstance<U, V>
{ {
fn fail<A: 'a>(e: E) -> Self::Fa<A> { fn fail<A: 'a>(e: E) -> Self::F<A> {
U::pure(V::fail(e)) U::pure(V::fail(e))
} }
} }
@ -127,11 +127,11 @@ 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> impl<'a, U: LocalFunctor<'a> + Functor<'a>, V: LocalFunctor<'a>> LocalFunctor<'a>
for CompositionInstance<U, V> for CompositionInstance<U, V>
{ {
fn unstuff<A: 'a, B: 'a>(state: Self::Fa<ControlFlow<B, A>>) -> ControlFlow<Self::Fa<B>, A> { fn unstuff<A: 'a, B: 'a>(state: Self::F<ControlFlow<B, A>>) -> ControlFlow<Self::F<B>, A> {
U::unstuff(U::fmap(V::unstuff, state)) U::unstuff(U::fmap(V::unstuff, state))
} }
fn stuff<A: 'a, T: Pure<'a>>(fa: Self::Fa<T::Fa<A>>) -> T::Fa<Self::Fa<A>> { fn stuff<A: 'a, T: Pure<'a>>(fa: Self::F<T::F<A>>) -> T::F<Self::F<A>> {
U::stuff::<_, T>(U::fmap(V::stuff::<_, T>, fa)) U::stuff::<_, T>(U::fmap(V::stuff::<_, T>, fa))
} }
} }
@ -141,11 +141,11 @@ impl<'a, U: SharedFunctor<'a> + Functor<'a>, V: SharedFunctor<'a>> SharedFunctor
{ {
type Shared<A: 'a + Clone> = U::Shared<V::Shared<A>>; type Shared<A: 'a + Clone> = U::Shared<V::Shared<A>>;
fn share<A: 'a + Clone>(fa: Self::Fa<A>) -> Self::Shared<A> { fn share<A: 'a + Clone>(fa: Self::F<A>) -> Self::Shared<A> {
U::share(U::fmap(V::share, fa)) U::share(U::fmap(V::share, fa))
} }
fn unshare<A: 'a + Clone>(sa: Self::Shared<A>) -> Self::Fa<A> { fn unshare<A: 'a + Clone>(sa: Self::Shared<A>) -> Self::F<A> {
U::fmap(V::unshare, U::unshare(sa)) U::fmap(V::unshare, U::unshare(sa))
} }
} }

View File

@ -26,21 +26,21 @@ impl<A, E: Effect> WithEffect<A, E> {
#[derive(SharedFunctorAny)] #[derive(SharedFunctorAny)]
pub struct EffectInstance<E>(E); pub struct EffectInstance<E>(E);
impl<E> WeakFunctor for EffectInstance<E> { impl<E> WeakFunctorAny for EffectInstance<E> {
type F<'a, A: 'a> = WithEffect<A, E> type FAny<'a, A: 'a> = WithEffect<A, E>
where where
Self: 'a; Self: 'a;
} }
impl<'a, E: 'a> Functor<'a> for EffectInstance<E> { impl<'a, E: 'a> Functor<'a> for EffectInstance<E> {
fn fmap<A: 'a, B: 'a>(f: impl 'a + FnOnce(A) -> B, fa: Self::Fa<A>) -> Self::Fa<B> { fn fmap<A: 'a, B: 'a>(f: impl 'a + FnOnce(A) -> B, fa: Self::F<A>) -> Self::F<B> {
WithEffect { WithEffect {
value: f(fa.value), value: f(fa.value),
effect: fa.effect, effect: fa.effect,
} }
} }
fn replace<A: 'a, B: 'a>(fa: Self::Fa<A>, b: B) -> Self::Fa<B> { fn replace<A: 'a, B: 'a>(fa: Self::F<A>, b: B) -> Self::F<B> {
drop(fa.value); drop(fa.value);
WithEffect { WithEffect {
value: b, value: b,
@ -50,7 +50,7 @@ impl<'a, E: 'a> Functor<'a> for EffectInstance<E> {
} }
impl<'a, E: 'a + Effect> Pure<'a> for EffectInstance<E> { impl<'a, E: 'a + Effect> Pure<'a> for EffectInstance<E> {
fn pure<A: 'a>(a: A) -> Self::Fa<A> { fn pure<A: 'a>(a: A) -> Self::F<A> {
WithEffect { WithEffect {
value: a, value: a,
effect: E::e_pure(), effect: E::e_pure(),
@ -59,7 +59,7 @@ impl<'a, E: 'a + Effect> Pure<'a> for EffectInstance<E> {
} }
impl<'a, E: 'a + Effect> ApplicativeSeq<'a> for EffectInstance<E> { impl<'a, E: 'a + Effect> ApplicativeSeq<'a> for EffectInstance<E> {
fn seq<A: 'a, B: 'a>(ff: Self::Fa<impl 'a + FnOnce(A) -> B>, fa: Self::Fa<A>) -> Self::Fa<B> { fn seq<A: 'a, B: 'a>(ff: Self::F<impl 'a + FnOnce(A) -> B>, fa: Self::F<A>) -> Self::F<B> {
WithEffect { WithEffect {
value: (ff.value)(fa.value), value: (ff.value)(fa.value),
effect: E::e_seq(ff.effect, fa.effect), effect: E::e_seq(ff.effect, fa.effect),
@ -70,9 +70,9 @@ impl<'a, E: 'a + Effect> ApplicativeSeq<'a> for EffectInstance<E> {
impl<'a, E: 'a + Effect> ApplicativeLA2<'a> for EffectInstance<E> { impl<'a, E: 'a + Effect> ApplicativeLA2<'a> for EffectInstance<E> {
fn la2<A: 'a, B: 'a, C: 'a>( fn la2<A: 'a, B: 'a, C: 'a>(
f: impl 'a + FnOnce(A, B) -> C, f: impl 'a + FnOnce(A, B) -> C,
fa: Self::Fa<A>, fa: Self::F<A>,
fb: Self::Fa<B>, fb: Self::F<B>,
) -> Self::Fa<C> { ) -> Self::F<C> {
WithEffect { WithEffect {
value: f(fa.value, fb.value), value: f(fa.value, fb.value),
effect: E::e_seq(fa.effect, fb.effect), effect: E::e_seq(fa.effect, fb.effect),
@ -81,7 +81,7 @@ impl<'a, E: 'a + Effect> ApplicativeLA2<'a> for EffectInstance<E> {
} }
impl<'a, E: 'a + Effect> ApplicativeTuple<'a> for EffectInstance<E> { impl<'a, E: 'a + Effect> ApplicativeTuple<'a> for EffectInstance<E> {
fn tuple<A: 'a, B: 'a>((fa, fb): (Self::Fa<A>, Self::Fa<B>)) -> Self::Fa<(A, B)> { fn tuple<A: 'a, B: 'a>((fa, fb): (Self::F<A>, Self::F<B>)) -> Self::F<(A, B)> {
WithEffect { WithEffect {
value: (fa.value, fb.value), value: (fa.value, fb.value),
effect: E::e_seq(fa.effect, fb.effect), effect: E::e_seq(fa.effect, fb.effect),
@ -92,7 +92,7 @@ impl<'a, E: 'a + Effect> ApplicativeTuple<'a> for EffectInstance<E> {
impl<'a, E: 'a + Effect> ApplicativeSelect<'a> for EffectInstance<E> {} impl<'a, E: 'a + Effect> ApplicativeSelect<'a> for EffectInstance<E> {}
impl<'a, E: 'a + Effect> Applicative<'a> for EffectInstance<E> { impl<'a, E: 'a + Effect> Applicative<'a> for EffectInstance<E> {
fn discard_first<A: 'a, B: 'a>(fa: Self::Fa<A>, fb: Self::Fa<B>) -> Self::Fa<B> { fn discard_first<A: 'a, B: 'a>(fa: Self::F<A>, fb: Self::F<B>) -> Self::F<B> {
drop(fa.value); drop(fa.value);
WithEffect { WithEffect {
value: fb.value, value: fb.value,
@ -100,7 +100,7 @@ impl<'a, E: 'a + Effect> Applicative<'a> for EffectInstance<E> {
} }
} }
fn discard_second<A: 'a, B: 'a>(fa: Self::Fa<A>, fb: Self::Fa<B>) -> Self::Fa<A> { fn discard_second<A: 'a, B: 'a>(fa: Self::F<A>, fb: Self::F<B>) -> Self::F<A> {
drop(fb.value); drop(fb.value);
WithEffect { WithEffect {
value: fa.value, value: fa.value,
@ -110,11 +110,11 @@ impl<'a, E: 'a + Effect> Applicative<'a> for EffectInstance<E> {
} }
impl<'a, E: 'a + Effect> Monad<'a> for EffectInstance<E> { impl<'a, E: 'a + Effect> Monad<'a> for EffectInstance<E> {
fn bind<A: 'a, B: 'a>(fa: Self::Fa<A>, f: impl 'a + FnOnce(A) -> Self::Fa<B>) -> Self::Fa<B> { fn bind<A: 'a, B: 'a>(fa: Self::F<A>, f: impl 'a + FnOnce(A) -> Self::F<B>) -> Self::F<B> {
f(fa.value).e_after(fa.effect) f(fa.value).e_after(fa.effect)
} }
fn iterate<B: 'a>(mut f: impl Iterative<'a, T = Self, B = B>) -> Self::Fa<B> { fn iterate<B: 'a>(mut f: impl Iterative<'a, T = Self, B = B>) -> Self::F<B> {
let mut effect = E::e_pure(); let mut effect = E::e_pure();
loop { loop {
let fa = f.next(); let fa = f.next();
@ -126,13 +126,13 @@ impl<'a, E: 'a + Effect> Monad<'a> for EffectInstance<E> {
} }
} }
fn join<A: 'a>(ffa: Self::Fa<Self::Fa<A>>) -> Self::Fa<A> { fn join<A: 'a>(ffa: Self::F<Self::F<A>>) -> Self::F<A> {
ffa.value.e_after(ffa.effect) ffa.value.e_after(ffa.effect)
} }
} }
impl<'a, E: 'a> LocalFunctor<'a> for EffectInstance<E> { impl<'a, E: 'a> LocalFunctor<'a> for EffectInstance<E> {
fn stuff<A: 'a, T: Pure<'a>>(fa: Self::Fa<T::Fa<A>>) -> T::Fa<Self::Fa<A>> { fn stuff<A: 'a, T: Pure<'a>>(fa: Self::F<T::F<A>>) -> T::F<Self::F<A>> {
T::fmap( T::fmap(
|a| WithEffect { |a| WithEffect {
value: a, value: a,

View File

@ -14,16 +14,16 @@ use crate::func::*;
pub struct FutureInstance; pub struct FutureInstance;
impl WeakFunctor for FutureInstance { impl WeakFunctorAny for FutureInstance {
type F<'a, A: 'a> = Pin<Box<dyn 'a + Future<Output = A>>>; type FAny<'a, A: 'a> = Pin<Box<dyn 'a + Future<Output = A>>>;
} }
impl<'a> Functor<'a> for FutureInstance { impl<'a> Functor<'a> for FutureInstance {
fn fmap<A: 'a, B: 'a>(f: impl 'a + FnOnce(A) -> B, fa: Self::Fa<A>) -> Self::Fa<B> { fn fmap<A: 'a, B: 'a>(f: impl 'a + FnOnce(A) -> B, fa: Self::F<A>) -> Self::F<B> {
Box::pin(async { f(fa.await) }) Box::pin(async { f(fa.await) })
} }
fn replace<A: 'a, B: 'a>(fa: Self::Fa<A>, b: B) -> Self::Fa<B> { fn replace<A: 'a, B: 'a>(fa: Self::F<A>, b: B) -> Self::F<B> {
Box::pin(async { Box::pin(async {
fa.await; fa.await;
b b
@ -32,13 +32,13 @@ impl<'a> Functor<'a> for FutureInstance {
} }
impl<'a> Pure<'a> for FutureInstance { impl<'a> Pure<'a> for FutureInstance {
fn pure<A: 'a>(a: A) -> Self::Fa<A> { fn pure<A: 'a>(a: A) -> Self::F<A> {
Box::pin(async { a }) Box::pin(async { a })
} }
} }
impl<'a> ApplicativeSeq<'a> for FutureInstance { impl<'a> ApplicativeSeq<'a> for FutureInstance {
fn seq<A: 'a, B: 'a>(ff: Self::Fa<impl 'a + FnOnce(A) -> B>, fa: Self::Fa<A>) -> Self::Fa<B> { fn seq<A: 'a, B: 'a>(ff: Self::F<impl 'a + FnOnce(A) -> B>, fa: Self::F<A>) -> Self::F<B> {
Box::pin(async { Box::pin(async {
let (f, a) = join!(ff, fa); let (f, a) = join!(ff, fa);
f(a) f(a)
@ -49,9 +49,9 @@ impl<'a> ApplicativeSeq<'a> for FutureInstance {
impl<'a> ApplicativeLA2<'a> for FutureInstance { impl<'a> ApplicativeLA2<'a> for FutureInstance {
fn la2<A: 'a, B: 'a, C: 'a>( fn la2<A: 'a, B: 'a, C: 'a>(
f: impl 'a + FnOnce(A, B) -> C, f: impl 'a + FnOnce(A, B) -> C,
fa: Self::Fa<A>, fa: Self::F<A>,
fb: Self::Fa<B>, fb: Self::F<B>,
) -> Self::Fa<C> { ) -> Self::F<C> {
Box::pin(async { Box::pin(async {
let (a, b) = join!(fa, fb); let (a, b) = join!(fa, fb);
f(a, b) f(a, b)
@ -60,13 +60,13 @@ impl<'a> ApplicativeLA2<'a> for FutureInstance {
} }
impl<'a> ApplicativeTuple<'a> for FutureInstance { impl<'a> ApplicativeTuple<'a> for FutureInstance {
fn tuple<A: 'a, B: 'a>((fa, fb): (Self::Fa<A>, Self::Fa<B>)) -> Self::Fa<(A, B)> { fn tuple<A: 'a, B: 'a>((fa, fb): (Self::F<A>, Self::F<B>)) -> Self::F<(A, B)> {
Box::pin(async { join!(fa, fb) }) Box::pin(async { join!(fa, fb) })
} }
} }
impl<'a> ApplicativeSelect<'a> for FutureInstance { impl<'a> ApplicativeSelect<'a> for FutureInstance {
fn select<A: 'a, B: 'a>(fa: Self::Fa<A>, fb: Self::Fa<B>) -> SelectedWrapped<'a, A, B, Self> { fn select<A: 'a, B: 'a>(fa: Self::F<A>, fb: Self::F<B>) -> SelectedWrapped<'a, A, B, Self> {
Box::pin(async { Box::pin(async {
match select(fa, fb).await { match select(fa, fb).await {
Either::Left((a, fb)) => Selected::A(a, fb), Either::Left((a, fb)) => Selected::A(a, fb),
@ -77,21 +77,21 @@ impl<'a> ApplicativeSelect<'a> for FutureInstance {
} }
impl<'a> Applicative<'a> for FutureInstance { impl<'a> Applicative<'a> for FutureInstance {
fn discard_first<A: 'a, B: 'a>(fa: Self::Fa<A>, fb: Self::Fa<B>) -> Self::Fa<B> { fn discard_first<A: 'a, B: 'a>(fa: Self::F<A>, fb: Self::F<B>) -> Self::F<B> {
Box::pin(async { join!(fa, fb).1 }) Box::pin(async { join!(fa, fb).1 })
} }
fn discard_second<A: 'a, B: 'a>(fa: Self::Fa<A>, fb: Self::Fa<B>) -> Self::Fa<A> { fn discard_second<A: 'a, B: 'a>(fa: Self::F<A>, fb: Self::F<B>) -> Self::F<A> {
Box::pin(async { join!(fa, fb).0 }) Box::pin(async { join!(fa, fb).0 })
} }
} }
impl<'a> Monad<'a> for FutureInstance { impl<'a> Monad<'a> for FutureInstance {
fn bind<A: 'a, B: 'a>(fa: Self::Fa<A>, f: impl 'a + FnOnce(A) -> Self::Fa<B>) -> Self::Fa<B> { fn bind<A: 'a, B: 'a>(fa: Self::F<A>, f: impl 'a + FnOnce(A) -> Self::F<B>) -> Self::F<B> {
Box::pin(async { f(fa.await).await }) Box::pin(async { f(fa.await).await })
} }
fn iterate<B: 'a>(mut f: impl Iterative<'a, T = Self, B = B>) -> Self::Fa<B> { fn iterate<B: 'a>(mut f: impl Iterative<'a, T = Self, B = B>) -> Self::F<B> {
Box::pin(async move { Box::pin(async move {
loop { loop {
match f.next().await { match f.next().await {
@ -102,7 +102,7 @@ impl<'a> Monad<'a> for FutureInstance {
}) })
} }
fn join<A: 'a>(ffa: Self::Fa<Self::Fa<A>>) -> Self::Fa<A> { fn join<A: 'a>(ffa: Self::F<Self::F<A>>) -> Self::F<A> {
Box::pin(async { ffa.await.await }) Box::pin(async { ffa.await.await })
} }
} }
@ -110,11 +110,11 @@ impl<'a> Monad<'a> for FutureInstance {
impl<'a> SharedFunctor<'a> for FutureInstance { impl<'a> SharedFunctor<'a> for FutureInstance {
type Shared<A: 'a + Clone> = Shared<Pin<Box<dyn 'a + Future<Output = A>>>>; type Shared<A: 'a + Clone> = Shared<Pin<Box<dyn 'a + Future<Output = A>>>>;
fn share<A: 'a + Clone>(fa: Self::Fa<A>) -> Self::Shared<A> { fn share<A: 'a + Clone>(fa: Self::F<A>) -> Self::Shared<A> {
fa.shared() fa.shared()
} }
fn unshare<A: 'a + Clone>(sa: Self::Shared<A>) -> Self::Fa<A> { fn unshare<A: 'a + Clone>(sa: Self::Shared<A>) -> Self::F<A> {
Box::pin(sa) Box::pin(sa)
} }
} }

View File

@ -13,34 +13,34 @@ use crate::func::*;
pub struct LazyInstance; pub struct LazyInstance;
impl WeakFunctor for LazyInstance { impl WeakFunctorAny for LazyInstance {
type F<'a, A: 'a> = Box<dyn 'a + FnOnce() -> A>; type FAny<'a, A: 'a> = Box<dyn 'a + FnOnce() -> A>;
} }
impl<'a> Functor<'a> for LazyInstance { impl<'a> Functor<'a> for LazyInstance {
fn fmap<A: 'a, B: 'a>(f: impl 'a + FnOnce(A) -> B, fa: Self::Fa<A>) -> Self::Fa<B> { fn fmap<A: 'a, B: 'a>(f: impl 'a + FnOnce(A) -> B, fa: Self::F<A>) -> Self::F<B> {
Box::new(|| f(fa())) Box::new(|| f(fa()))
} }
fn replace<A: 'a, B: 'a>(fa: Self::Fa<A>, b: B) -> Self::Fa<B> { fn replace<A: 'a, B: 'a>(fa: Self::F<A>, b: B) -> Self::F<B> {
drop(fa); drop(fa);
Box::new(|| b) Box::new(|| b)
} }
fn void<A: 'a>(fa: Self::Fa<A>) -> Self::Fa<()> { fn void<A: 'a>(fa: Self::F<A>) -> Self::F<()> {
drop(fa); drop(fa);
Box::new(|| ()) Box::new(|| ())
} }
} }
impl<'a> Pure<'a> for LazyInstance { impl<'a> Pure<'a> for LazyInstance {
fn pure<A: 'a>(a: A) -> Self::Fa<A> { fn pure<A: 'a>(a: A) -> Self::F<A> {
Box::new(|| a) Box::new(|| a)
} }
} }
impl<'a> ApplicativeSeq<'a> for LazyInstance { impl<'a> ApplicativeSeq<'a> for LazyInstance {
fn seq<A: 'a, B: 'a>(ff: Self::Fa<impl 'a + FnOnce(A) -> B>, fa: Self::Fa<A>) -> Self::Fa<B> { fn seq<A: 'a, B: 'a>(ff: Self::F<impl 'a + FnOnce(A) -> B>, fa: Self::F<A>) -> Self::F<B> {
Box::new(|| ff()(fa())) Box::new(|| ff()(fa()))
} }
} }
@ -48,15 +48,15 @@ impl<'a> ApplicativeSeq<'a> for LazyInstance {
impl<'a> ApplicativeLA2<'a> for LazyInstance { impl<'a> ApplicativeLA2<'a> for LazyInstance {
fn la2<A: 'a, B: 'a, C: 'a>( fn la2<A: 'a, B: 'a, C: 'a>(
f: impl 'a + FnOnce(A, B) -> C, f: impl 'a + FnOnce(A, B) -> C,
fa: Self::Fa<A>, fa: Self::F<A>,
fb: Self::Fa<B>, fb: Self::F<B>,
) -> Self::Fa<C> { ) -> Self::F<C> {
Box::new(|| f(fa(), fb())) Box::new(|| f(fa(), fb()))
} }
} }
impl<'a> ApplicativeTuple<'a> for LazyInstance { impl<'a> ApplicativeTuple<'a> for LazyInstance {
fn tuple<A: 'a, B: 'a>((fa, fb): (Self::Fa<A>, Self::Fa<B>)) -> Self::Fa<(A, B)> { fn tuple<A: 'a, B: 'a>((fa, fb): (Self::F<A>, Self::F<B>)) -> Self::F<(A, B)> {
Box::new(|| (fa(), fb())) Box::new(|| (fa(), fb()))
} }
} }
@ -64,23 +64,23 @@ impl<'a> ApplicativeTuple<'a> for LazyInstance {
impl<'a> ApplicativeSelect<'a> for LazyInstance {} impl<'a> ApplicativeSelect<'a> for LazyInstance {}
impl<'a> Applicative<'a> for LazyInstance { impl<'a> Applicative<'a> for LazyInstance {
fn discard_first<A: 'a, B: 'a>(fa: Self::Fa<A>, fb: Self::Fa<B>) -> Self::Fa<B> { fn discard_first<A: 'a, B: 'a>(fa: Self::F<A>, fb: Self::F<B>) -> Self::F<B> {
drop(fa); drop(fa);
fb fb
} }
fn discard_second<A: 'a, B: 'a>(fa: Self::Fa<A>, fb: Self::Fa<B>) -> Self::Fa<A> { fn discard_second<A: 'a, B: 'a>(fa: Self::F<A>, fb: Self::F<B>) -> Self::F<A> {
drop(fb); drop(fb);
fa fa
} }
} }
impl<'a> Monad<'a> for LazyInstance { impl<'a> Monad<'a> for LazyInstance {
fn bind<A: 'a, B: 'a>(fa: Self::Fa<A>, f: impl 'a + FnOnce(A) -> Self::Fa<B>) -> Self::Fa<B> { fn bind<A: 'a, B: 'a>(fa: Self::F<A>, f: impl 'a + FnOnce(A) -> Self::F<B>) -> Self::F<B> {
Box::new(|| f(fa())()) Box::new(|| f(fa())())
} }
fn iterate<B: 'a>(mut f: impl Iterative<'a, T = Self, B = B>) -> Self::Fa<B> { fn iterate<B: 'a>(mut f: impl Iterative<'a, T = Self, B = B>) -> Self::F<B> {
loop { loop {
match f.next()() { match f.next()() {
ControlFlow::Continue(next_f) => f = next_f, ControlFlow::Continue(next_f) => f = next_f,
@ -89,7 +89,7 @@ impl<'a> Monad<'a> for LazyInstance {
} }
} }
fn join<A: 'a>(ffa: Self::Fa<Self::Fa<A>>) -> Self::Fa<A> { fn join<A: 'a>(ffa: Self::F<Self::F<A>>) -> Self::F<A> {
Box::new(|| ffa()()) Box::new(|| ffa()())
} }
} }
@ -106,11 +106,11 @@ fn unshare<'a, A: 'a + Clone>(shared: &mut Option<Box<dyn 'a + FnOnce() -> A>>)
impl<'a> SharedFunctor<'a> for LazyInstance { impl<'a> SharedFunctor<'a> for LazyInstance {
type Shared<A: 'a + Clone> = Rc<RefCell<Option<Box<dyn 'a + FnOnce() -> A>>>>; type Shared<A: 'a + Clone> = Rc<RefCell<Option<Box<dyn 'a + FnOnce() -> A>>>>;
fn share<A: 'a + Clone>(fa: Self::Fa<A>) -> Self::Shared<A> { fn share<A: 'a + Clone>(fa: Self::F<A>) -> Self::Shared<A> {
Rc::new(RefCell::new(Some(fa))) Rc::new(RefCell::new(Some(fa)))
} }
fn unshare<A: 'a + Clone>(sa: Self::Shared<A>) -> Self::Fa<A> { fn unshare<A: 'a + Clone>(sa: Self::Shared<A>) -> Self::F<A> {
Box::new(move || unshare(&mut *sa.borrow_mut())) Box::new(move || unshare(&mut *sa.borrow_mut()))
} }
} }

View File

@ -12,34 +12,34 @@ use crate::func::*;
#[derive(SharedFunctorAny)] #[derive(SharedFunctorAny)]
pub struct OptionInstance; pub struct OptionInstance;
impl WeakFunctor for OptionInstance { impl WeakFunctorAny for OptionInstance {
type F<'a, A: 'a> = Option<A>; type FAny<'a, A: 'a> = Option<A>;
} }
impl<'a> Functor<'a> for OptionInstance { impl<'a> Functor<'a> for OptionInstance {
fn fmap<A: 'a, B: 'a>(f: impl 'a + FnOnce(A) -> B, fa: Self::Fa<A>) -> Self::Fa<B> { fn fmap<A: 'a, B: 'a>(f: impl 'a + FnOnce(A) -> B, fa: Self::F<A>) -> Self::F<B> {
fa.map(f) fa.map(f)
} }
fn replace<A: 'a, B: 'a>(fa: Self::Fa<A>, b: B) -> Self::Fa<B> { fn replace<A: 'a, B: 'a>(fa: Self::F<A>, b: B) -> Self::F<B> {
fa?; fa?;
Self::pure(b) Self::pure(b)
} }
fn void<A: 'a>(fa: Self::Fa<A>) -> Self::Fa<()> { fn void<A: 'a>(fa: Self::F<A>) -> Self::F<()> {
fa?; fa?;
Self::pure(()) Self::pure(())
} }
} }
impl<'a> Pure<'a> for OptionInstance { impl<'a> Pure<'a> for OptionInstance {
fn pure<A: 'a>(a: A) -> Self::Fa<A> { fn pure<A: 'a>(a: A) -> Self::F<A> {
Some(a) Some(a)
} }
} }
impl<'a> ApplicativeSeq<'a> for OptionInstance { impl<'a> ApplicativeSeq<'a> for OptionInstance {
fn seq<A: 'a, B: 'a>(ff: Self::Fa<impl 'a + FnOnce(A) -> B>, fa: Self::Fa<A>) -> Self::Fa<B> { fn seq<A: 'a, B: 'a>(ff: Self::F<impl 'a + FnOnce(A) -> B>, fa: Self::F<A>) -> Self::F<B> {
Self::pure(ff?(fa?)) Self::pure(ff?(fa?))
} }
} }
@ -47,15 +47,15 @@ impl<'a> ApplicativeSeq<'a> for OptionInstance {
impl<'a> ApplicativeLA2<'a> for OptionInstance { impl<'a> ApplicativeLA2<'a> for OptionInstance {
fn la2<A: 'a, B: 'a, C: 'a>( fn la2<A: 'a, B: 'a, C: 'a>(
f: impl 'a + FnOnce(A, B) -> C, f: impl 'a + FnOnce(A, B) -> C,
fa: Self::Fa<A>, fa: Self::F<A>,
fb: Self::Fa<B>, fb: Self::F<B>,
) -> Self::Fa<C> { ) -> Self::F<C> {
Self::pure(f(fa?, fb?)) Self::pure(f(fa?, fb?))
} }
} }
impl<'a> ApplicativeTuple<'a> for OptionInstance { impl<'a> ApplicativeTuple<'a> for OptionInstance {
fn tuple<A: 'a, B: 'a>((fa, fb): (Self::Fa<A>, Self::Fa<B>)) -> Self::Fa<(A, B)> { fn tuple<A: 'a, B: 'a>((fa, fb): (Self::F<A>, Self::F<B>)) -> Self::F<(A, B)> {
Self::pure((fa?, fb?)) Self::pure((fa?, fb?))
} }
} }
@ -63,23 +63,23 @@ impl<'a> ApplicativeTuple<'a> for OptionInstance {
impl<'a> ApplicativeSelect<'a> for OptionInstance {} impl<'a> ApplicativeSelect<'a> for OptionInstance {}
impl<'a> Applicative<'a> for OptionInstance { impl<'a> Applicative<'a> for OptionInstance {
fn discard_first<A: 'a, B: 'a>(fa: Self::Fa<A>, fb: Self::Fa<B>) -> Self::Fa<B> { fn discard_first<A: 'a, B: 'a>(fa: Self::F<A>, fb: Self::F<B>) -> Self::F<B> {
fa?; fa?;
fb fb
} }
fn discard_second<A: 'a, B: 'a>(fa: Self::Fa<A>, fb: Self::Fa<B>) -> Self::Fa<A> { fn discard_second<A: 'a, B: 'a>(fa: Self::F<A>, fb: Self::F<B>) -> Self::F<A> {
fb?; fb?;
fa fa
} }
} }
impl<'a> Monad<'a> for OptionInstance { impl<'a> Monad<'a> for OptionInstance {
fn bind<A: 'a, B: 'a>(fa: Self::Fa<A>, f: impl 'a + FnOnce(A) -> Self::Fa<B>) -> Self::Fa<B> { fn bind<A: 'a, B: 'a>(fa: Self::F<A>, f: impl 'a + FnOnce(A) -> Self::F<B>) -> Self::F<B> {
f(fa?) f(fa?)
} }
fn iterate<B: 'a>(mut f: impl Iterative<'a, T = Self, B = B>) -> Self::Fa<B> { fn iterate<B: 'a>(mut f: impl Iterative<'a, T = Self, B = B>) -> Self::F<B> {
loop { loop {
match f.next()? { match f.next()? {
ControlFlow::Continue(next_f) => f = next_f, ControlFlow::Continue(next_f) => f = next_f,
@ -88,13 +88,13 @@ impl<'a> Monad<'a> for OptionInstance {
} }
} }
fn join<A: 'a>(ffa: Self::Fa<Self::Fa<A>>) -> Self::Fa<A> { fn join<A: 'a>(ffa: Self::F<Self::F<A>>) -> Self::F<A> {
ffa? ffa?
} }
} }
impl<'a> LocalFunctor<'a> for OptionInstance { impl<'a> LocalFunctor<'a> for OptionInstance {
fn unstuff<A: 'a, B: 'a>(state: Self::Fa<ControlFlow<B, A>>) -> ControlFlow<Self::Fa<B>, A> { fn unstuff<A: 'a, B: 'a>(state: Self::F<ControlFlow<B, A>>) -> ControlFlow<Self::F<B>, A> {
match state { match state {
Some(ControlFlow::Continue(a)) => ControlFlow::Continue(a), Some(ControlFlow::Continue(a)) => ControlFlow::Continue(a),
Some(ControlFlow::Break(b)) => ControlFlow::Break(Some(b)), Some(ControlFlow::Break(b)) => ControlFlow::Break(Some(b)),
@ -102,7 +102,7 @@ impl<'a> LocalFunctor<'a> for OptionInstance {
} }
} }
fn stuff<A: 'a, T: Pure<'a>>(fa: Self::Fa<T::Fa<A>>) -> T::Fa<Self::Fa<A>> { fn stuff<A: 'a, T: Pure<'a>>(fa: Self::F<T::F<A>>) -> T::F<Self::F<A>> {
match fa { match fa {
Some(ua) => T::fmap(Some, ua), Some(ua) => T::fmap(Some, ua),
None => T::pure(None), None => T::pure(None),
@ -111,7 +111,7 @@ impl<'a> LocalFunctor<'a> for OptionInstance {
} }
impl<'a> Fail<'a, ()> for OptionInstance { impl<'a> Fail<'a, ()> for OptionInstance {
fn fail<A: 'a>(_e: ()) -> Self::Fa<A> { fn fail<A: 'a>(_e: ()) -> Self::F<A> {
None None
} }
} }
@ -125,15 +125,15 @@ mod option_tests {
impl<'a> tests::Eqr<'a> for T { impl<'a> tests::Eqr<'a> for T {
fn eqr<A: PartialEq + std::fmt::Debug + 'a>( fn eqr<A: PartialEq + std::fmt::Debug + 'a>(
name: &'a str, name: &'a str,
left: Self::Fa<A>, left: Self::F<A>,
right: Self::Fa<A>, right: Self::F<A>,
) -> tests::R { ) -> tests::R {
tests::eqr(name, left, right) tests::eqr(name, left, right)
} }
} }
impl<'a> test_suite::FunctorTestSuite<'a> for T { impl<'a> test_suite::FunctorTestSuite<'a> for T {
fn sample<A: 'a, F: FnMut(&'a dyn Fn(A) -> Self::Fa<A>)>(mut f: F) { fn sample<A: 'a, F: FnMut(&'a dyn Fn(A) -> Self::F<A>)>(mut f: F) {
f(&|_| None); f(&|_| None);
f(&|a| Some(a)); f(&|a| Some(a));
} }

View File

@ -12,28 +12,26 @@ pub trait DeriveApplicative {}
impl<O: DeriveMonad> DeriveApplicative for O {} impl<O: DeriveMonad> DeriveApplicative for O {}
pub trait DeriveMonad {} pub trait DeriveMonad {}
impl<'a, T: WeakFunctorA<'a>, O: 'a + DeriveWeakFunctor> WeakFunctorA<'a> impl<'a, T: WeakFunctor<'a>, O: 'a + DeriveWeakFunctor> WeakFunctor<'a> for OverloadInstance<T, O> {
for OverloadInstance<T, O> type F<A: 'a> = T::F<A>;
{
type Fa<A: 'a> = T::Fa<A>;
} }
impl<'a, T: Functor<'a>, O: 'a + DeriveFunctor> Functor<'a> for OverloadInstance<T, O> { impl<'a, T: Functor<'a>, O: 'a + DeriveFunctor> Functor<'a> for OverloadInstance<T, O> {
fn fmap<A: 'a, B: 'a>(f: impl 'a + FnOnce(A) -> B, fa: Self::Fa<A>) -> Self::Fa<B> { fn fmap<A: 'a, B: 'a>(f: impl 'a + FnOnce(A) -> B, fa: Self::F<A>) -> Self::F<B> {
T::fmap(f, fa) T::fmap(f, fa)
} }
fn replace<A: 'a, B: 'a>(fa: Self::Fa<A>, b: B) -> Self::Fa<B> { fn replace<A: 'a, B: 'a>(fa: Self::F<A>, b: B) -> Self::F<B> {
T::replace(fa, b) T::replace(fa, b)
} }
fn void<A: 'a>(fa: Self::Fa<A>) -> Self::Fa<()> { fn void<A: 'a>(fa: Self::F<A>) -> Self::F<()> {
T::void(fa) T::void(fa)
} }
} }
impl<'a, T: Pure<'a>, O: 'a + DeriveApplicative> Pure<'a> for OverloadInstance<T, O> { impl<'a, T: Pure<'a>, O: 'a + DeriveApplicative> Pure<'a> for OverloadInstance<T, O> {
fn pure<A: 'a>(a: A) -> Self::Fa<A> { fn pure<A: 'a>(a: A) -> Self::F<A> {
T::pure(a) T::pure(a)
} }
} }
@ -41,7 +39,7 @@ impl<'a, T: Pure<'a>, O: 'a + DeriveApplicative> Pure<'a> for OverloadInstance<T
impl<'a, T: ApplicativeSeq<'a>, O: 'a + DeriveApplicative> ApplicativeSeq<'a> impl<'a, T: ApplicativeSeq<'a>, O: 'a + DeriveApplicative> ApplicativeSeq<'a>
for OverloadInstance<T, O> for OverloadInstance<T, O>
{ {
fn seq<A: 'a, B: 'a>(ff: Self::Fa<impl 'a + FnOnce(A) -> B>, fa: Self::Fa<A>) -> Self::Fa<B> { fn seq<A: 'a, B: 'a>(ff: Self::F<impl 'a + FnOnce(A) -> B>, fa: Self::F<A>) -> Self::F<B> {
T::seq(ff, fa) T::seq(ff, fa)
} }
} }
@ -51,9 +49,9 @@ impl<'a, T: ApplicativeLA2<'a>, O: 'a + DeriveApplicative> ApplicativeLA2<'a>
{ {
fn la2<A: 'a, B: 'a, C: 'a>( fn la2<A: 'a, B: 'a, C: 'a>(
f: impl 'a + FnOnce(A, B) -> C, f: impl 'a + FnOnce(A, B) -> C,
fa: Self::Fa<A>, fa: Self::F<A>,
fb: Self::Fa<B>, fb: Self::F<B>,
) -> Self::Fa<C> { ) -> Self::F<C> {
T::la2(f, fa, fb) T::la2(f, fa, fb)
} }
} }
@ -61,7 +59,7 @@ impl<'a, T: ApplicativeLA2<'a>, O: 'a + DeriveApplicative> ApplicativeLA2<'a>
impl<'a, T: ApplicativeTuple<'a>, O: 'a + DeriveApplicative> ApplicativeTuple<'a> impl<'a, T: ApplicativeTuple<'a>, O: 'a + DeriveApplicative> ApplicativeTuple<'a>
for OverloadInstance<T, O> for OverloadInstance<T, O>
{ {
fn tuple<A: 'a, B: 'a>(fab: (Self::Fa<A>, Self::Fa<B>)) -> Self::Fa<(A, B)> { fn tuple<A: 'a, B: 'a>(fab: (Self::F<A>, Self::F<B>)) -> Self::F<(A, B)> {
T::tuple(fab) T::tuple(fab)
} }
} }
@ -69,7 +67,7 @@ impl<'a, T: ApplicativeTuple<'a>, O: 'a + DeriveApplicative> ApplicativeTuple<'a
impl<'a, T: ApplicativeSelect<'a>, O: 'a + DeriveApplicative> ApplicativeSelect<'a> impl<'a, T: ApplicativeSelect<'a>, O: 'a + DeriveApplicative> ApplicativeSelect<'a>
for OverloadInstance<T, O> for OverloadInstance<T, O>
{ {
fn select<A: 'a, B: 'a>(fa: Self::Fa<A>, fb: Self::Fa<B>) -> SelectedWrapped<'a, A, B, Self> { fn select<A: 'a, B: 'a>(fa: Self::F<A>, fb: Self::F<B>) -> SelectedWrapped<'a, A, B, Self> {
T::select_map( T::select_map(
|selected| match selected { |selected| match selected {
Selected::A(a, fb) => Selected::A(a, fb), Selected::A(a, fb) => Selected::A(a, fb),
@ -82,11 +80,11 @@ impl<'a, T: ApplicativeSelect<'a>, O: 'a + DeriveApplicative> ApplicativeSelect<
} }
impl<'a, T: Applicative<'a>, O: 'a + DeriveApplicative> Applicative<'a> for OverloadInstance<T, O> { impl<'a, T: Applicative<'a>, O: 'a + DeriveApplicative> Applicative<'a> for OverloadInstance<T, O> {
fn discard_first<A: 'a, B: 'a>(fa: Self::Fa<A>, fb: Self::Fa<B>) -> Self::Fa<B> { fn discard_first<A: 'a, B: 'a>(fa: Self::F<A>, fb: Self::F<B>) -> Self::F<B> {
T::discard_first(fa, fb) T::discard_first(fa, fb)
} }
fn discard_second<A: 'a, B: 'a>(fa: Self::Fa<A>, fb: Self::Fa<B>) -> Self::Fa<A> { fn discard_second<A: 'a, B: 'a>(fa: Self::F<A>, fb: Self::F<B>) -> Self::F<A> {
T::discard_second(fa, fb) T::discard_second(fa, fb)
} }
} }
@ -118,15 +116,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<T, O> { impl<'a, T: Monad<'a>, O: 'a + DeriveMonad> Monad<'a> for OverloadInstance<T, O> {
fn bind<A: 'a, B: 'a>(fa: Self::Fa<A>, f: impl 'a + FnOnce(A) -> Self::Fa<B>) -> Self::Fa<B> { fn bind<A: 'a, B: 'a>(fa: Self::F<A>, f: impl 'a + FnOnce(A) -> Self::F<B>) -> Self::F<B> {
T::bind(fa, f) T::bind(fa, f)
} }
fn iterate<B: 'a>(f: impl Iterative<'a, T = Self, B = B>) -> Self::Fa<B> { fn iterate<B: 'a>(f: impl Iterative<'a, T = Self, B = B>) -> Self::F<B> {
T::iterate(OverloadIterative::new(f)) T::iterate(OverloadIterative::new(f))
} }
fn join<A: 'a>(ffa: Self::Fa<Self::Fa<A>>) -> Self::Fa<A> { fn join<A: 'a>(ffa: Self::F<Self::F<A>>) -> Self::F<A> {
T::join(ffa) T::join(ffa)
} }
} }
@ -138,7 +136,7 @@ impl<Ex> DeriveMonad for DeriveFail<Ex> {}
impl<'a, E: 'a, Ex: 'a, T: MonadFail<'a, Result<E, Ex>>> Fail<'a, E> impl<'a, E: 'a, Ex: 'a, T: MonadFail<'a, Result<E, Ex>>> Fail<'a, E>
for OverloadInstance<T, DeriveFail<Ex>> for OverloadInstance<T, DeriveFail<Ex>>
{ {
fn fail<A: 'a>(e: E) -> Self::Fa<A> { fn fail<A: 'a>(e: E) -> Self::F<A> {
T::fail(Ok(e)) T::fail(Ok(e))
} }
} }
@ -199,11 +197,11 @@ impl<'a, T: SharedFunctor<'a>, O: 'a + DeriveWeakFunctor> SharedFunctor<'a>
{ {
type Shared<A: 'a + Clone> = T::Shared<A>; type Shared<A: 'a + Clone> = T::Shared<A>;
fn share<A: 'a + Clone>(fa: Self::Fa<A>) -> Self::Shared<A> { fn share<A: 'a + Clone>(fa: Self::F<A>) -> Self::Shared<A> {
T::share(fa) T::share(fa)
} }
fn unshare<A: 'a + Clone>(sa: Self::Shared<A>) -> Self::Fa<A> { fn unshare<A: 'a + Clone>(sa: Self::Shared<A>) -> Self::F<A> {
T::unshare(sa) T::unshare(sa)
} }
} }

View File

@ -12,34 +12,34 @@ use crate::func::*;
#[derive(SharedFunctorAny)] #[derive(SharedFunctorAny)]
pub struct ResultInstance<E>(E); pub struct ResultInstance<E>(E);
impl<E> WeakFunctor for ResultInstance<E> { impl<E> WeakFunctorAny for ResultInstance<E> {
type F<'a, A: 'a> = Result<A, E> where Self: 'a; type FAny<'a, A: 'a> = Result<A, E> where Self: 'a;
} }
impl<'a, E: 'a> Functor<'a> for ResultInstance<E> { impl<'a, E: 'a> Functor<'a> for ResultInstance<E> {
fn fmap<A: 'a, B: 'a>(f: impl 'a + FnOnce(A) -> B, fa: Self::Fa<A>) -> Self::Fa<B> { fn fmap<A: 'a, B: 'a>(f: impl 'a + FnOnce(A) -> B, fa: Self::F<A>) -> Self::F<B> {
fa.map(f) fa.map(f)
} }
fn replace<A: 'a, B: 'a>(fa: Self::Fa<A>, b: B) -> Self::Fa<B> { fn replace<A: 'a, B: 'a>(fa: Self::F<A>, b: B) -> Self::F<B> {
fa?; fa?;
Self::pure(b) Self::pure(b)
} }
fn void<A: 'a>(fa: Self::Fa<A>) -> Self::Fa<()> { fn void<A: 'a>(fa: Self::F<A>) -> Self::F<()> {
fa?; fa?;
Self::pure(()) Self::pure(())
} }
} }
impl<'a, E: 'a> Pure<'a> for ResultInstance<E> { impl<'a, E: 'a> Pure<'a> for ResultInstance<E> {
fn pure<A: 'a>(a: A) -> Self::Fa<A> { fn pure<A: 'a>(a: A) -> Self::F<A> {
Ok(a) Ok(a)
} }
} }
impl<'a, E: 'a> ApplicativeSeq<'a> for ResultInstance<E> { impl<'a, E: 'a> ApplicativeSeq<'a> for ResultInstance<E> {
fn seq<A: 'a, B: 'a>(ff: Self::Fa<impl 'a + FnOnce(A) -> B>, fa: Self::Fa<A>) -> Self::Fa<B> { fn seq<A: 'a, B: 'a>(ff: Self::F<impl 'a + FnOnce(A) -> B>, fa: Self::F<A>) -> Self::F<B> {
Self::pure(ff?(fa?)) Self::pure(ff?(fa?))
} }
} }
@ -47,15 +47,15 @@ impl<'a, E: 'a> ApplicativeSeq<'a> for ResultInstance<E> {
impl<'a, E: 'a> ApplicativeLA2<'a> for ResultInstance<E> { impl<'a, E: 'a> ApplicativeLA2<'a> for ResultInstance<E> {
fn la2<A: 'a, B: 'a, C: 'a>( fn la2<A: 'a, B: 'a, C: 'a>(
f: impl 'a + FnOnce(A, B) -> C, f: impl 'a + FnOnce(A, B) -> C,
fa: Self::Fa<A>, fa: Self::F<A>,
fb: Self::Fa<B>, fb: Self::F<B>,
) -> Self::Fa<C> { ) -> Self::F<C> {
Self::pure(f(fa?, fb?)) Self::pure(f(fa?, fb?))
} }
} }
impl<'a, E: 'a> ApplicativeTuple<'a> for ResultInstance<E> { impl<'a, E: 'a> ApplicativeTuple<'a> for ResultInstance<E> {
fn tuple<A: 'a, B: 'a>((fa, fb): (Self::Fa<A>, Self::Fa<B>)) -> Self::Fa<(A, B)> { fn tuple<A: 'a, B: 'a>((fa, fb): (Self::F<A>, Self::F<B>)) -> Self::F<(A, B)> {
Self::pure((fa?, fb?)) Self::pure((fa?, fb?))
} }
} }
@ -63,23 +63,23 @@ impl<'a, E: 'a> ApplicativeTuple<'a> for ResultInstance<E> {
impl<'a, E: 'a> ApplicativeSelect<'a> for ResultInstance<E> {} impl<'a, E: 'a> ApplicativeSelect<'a> for ResultInstance<E> {}
impl<'a, E: 'a> Applicative<'a> for ResultInstance<E> { impl<'a, E: 'a> Applicative<'a> for ResultInstance<E> {
fn discard_first<A: 'a, B: 'a>(fa: Self::Fa<A>, fb: Self::Fa<B>) -> Self::Fa<B> { fn discard_first<A: 'a, B: 'a>(fa: Self::F<A>, fb: Self::F<B>) -> Self::F<B> {
fa?; fa?;
fb fb
} }
fn discard_second<A: 'a, B: 'a>(fa: Self::Fa<A>, fb: Self::Fa<B>) -> Self::Fa<A> { fn discard_second<A: 'a, B: 'a>(fa: Self::F<A>, fb: Self::F<B>) -> Self::F<A> {
fb?; fb?;
fa fa
} }
} }
impl<'a, E: 'a> Monad<'a> for ResultInstance<E> { impl<'a, E: 'a> Monad<'a> for ResultInstance<E> {
fn bind<A: 'a, B: 'a>(fa: Self::Fa<A>, f: impl 'a + FnOnce(A) -> Self::Fa<B>) -> Self::Fa<B> { fn bind<A: 'a, B: 'a>(fa: Self::F<A>, f: impl 'a + FnOnce(A) -> Self::F<B>) -> Self::F<B> {
f(fa?) f(fa?)
} }
fn iterate<B: 'a>(mut f: impl Iterative<'a, T = Self, B = B>) -> Self::Fa<B> { fn iterate<B: 'a>(mut f: impl Iterative<'a, T = Self, B = B>) -> Self::F<B> {
loop { loop {
match f.next()? { match f.next()? {
ControlFlow::Continue(next_f) => f = next_f, ControlFlow::Continue(next_f) => f = next_f,
@ -88,13 +88,13 @@ impl<'a, E: 'a> Monad<'a> for ResultInstance<E> {
} }
} }
fn join<A: 'a>(ffa: Self::Fa<Self::Fa<A>>) -> Self::Fa<A> { fn join<A: 'a>(ffa: Self::F<Self::F<A>>) -> Self::F<A> {
ffa? ffa?
} }
} }
impl<'a, E: 'a> LocalFunctor<'a> for ResultInstance<E> { impl<'a, E: 'a> LocalFunctor<'a> for ResultInstance<E> {
fn unstuff<A: 'a, B: 'a>(state: Self::Fa<ControlFlow<B, A>>) -> ControlFlow<Self::Fa<B>, A> { fn unstuff<A: 'a, B: 'a>(state: Self::F<ControlFlow<B, A>>) -> ControlFlow<Self::F<B>, A> {
match state { match state {
Ok(ControlFlow::Continue(a)) => ControlFlow::Continue(a), Ok(ControlFlow::Continue(a)) => ControlFlow::Continue(a),
Ok(ControlFlow::Break(b)) => ControlFlow::Break(Ok(b)), Ok(ControlFlow::Break(b)) => ControlFlow::Break(Ok(b)),
@ -102,7 +102,7 @@ impl<'a, E: 'a> LocalFunctor<'a> for ResultInstance<E> {
} }
} }
fn stuff<A: 'a, T: Pure<'a>>(fa: Self::Fa<T::Fa<A>>) -> T::Fa<Self::Fa<A>> { fn stuff<A: 'a, T: Pure<'a>>(fa: Self::F<T::F<A>>) -> T::F<Self::F<A>> {
match fa { match fa {
Ok(ua) => T::fmap(Ok, ua), Ok(ua) => T::fmap(Ok, ua),
Err(e) => T::pure(Err(e)), Err(e) => T::pure(Err(e)),
@ -111,7 +111,7 @@ impl<'a, E: 'a> LocalFunctor<'a> for ResultInstance<E> {
} }
impl<'a, E: 'a> Fail<'a, E> for ResultInstance<E> { impl<'a, E: 'a> Fail<'a, E> for ResultInstance<E> {
fn fail<A: 'a>(e: E) -> Self::Fa<A> { fn fail<A: 'a>(e: E) -> Self::F<A> {
Err(e) Err(e)
} }
} }

View File

@ -7,33 +7,33 @@ use crate::func::*;
#[derive(SharedFunctorAny)] #[derive(SharedFunctorAny)]
pub struct SoloInstance; pub struct SoloInstance;
impl WeakFunctor for SoloInstance { impl WeakFunctorAny for SoloInstance {
type F<'a, A: 'a> = A; type FAny<'a, A: 'a> = A;
} }
impl<'a> Functor<'a> for SoloInstance { impl<'a> Functor<'a> for SoloInstance {
fn fmap<A: 'a, B: 'a>(f: impl 'a + FnOnce(A) -> B, fa: Self::Fa<A>) -> Self::Fa<B> { fn fmap<A: 'a, B: 'a>(f: impl 'a + FnOnce(A) -> B, fa: Self::F<A>) -> Self::F<B> {
f(fa) f(fa)
} }
fn replace<A: 'a, B: 'a>(fa: Self::Fa<A>, b: B) -> Self::Fa<B> { fn replace<A: 'a, B: 'a>(fa: Self::F<A>, b: B) -> Self::F<B> {
drop(fa); drop(fa);
b b
} }
fn void<A: 'a>(fa: Self::Fa<A>) -> Self::Fa<()> { fn void<A: 'a>(fa: Self::F<A>) -> Self::F<()> {
drop(fa); drop(fa);
} }
} }
impl<'a> Pure<'a> for SoloInstance { impl<'a> Pure<'a> for SoloInstance {
fn pure<A: 'a>(a: A) -> Self::Fa<A> { fn pure<A: 'a>(a: A) -> Self::F<A> {
a a
} }
} }
impl<'a> ApplicativeSeq<'a> for SoloInstance { impl<'a> ApplicativeSeq<'a> for SoloInstance {
fn seq<A: 'a, B: 'a>(ff: Self::Fa<impl 'a + FnOnce(A) -> B>, fa: Self::Fa<A>) -> Self::Fa<B> { fn seq<A: 'a, B: 'a>(ff: Self::F<impl 'a + FnOnce(A) -> B>, fa: Self::F<A>) -> Self::F<B> {
ff(fa) ff(fa)
} }
} }
@ -41,15 +41,15 @@ impl<'a> ApplicativeSeq<'a> for SoloInstance {
impl<'a> ApplicativeLA2<'a> for SoloInstance { impl<'a> ApplicativeLA2<'a> for SoloInstance {
fn la2<A: 'a, B: 'a, C: 'a>( fn la2<A: 'a, B: 'a, C: 'a>(
f: impl 'a + FnOnce(A, B) -> C, f: impl 'a + FnOnce(A, B) -> C,
fa: Self::Fa<A>, fa: Self::F<A>,
fb: Self::Fa<B>, fb: Self::F<B>,
) -> Self::Fa<C> { ) -> Self::F<C> {
f(fa, fb) f(fa, fb)
} }
} }
impl<'a> ApplicativeTuple<'a> for SoloInstance { impl<'a> ApplicativeTuple<'a> for SoloInstance {
fn tuple<A: 'a, B: 'a>((fa, fb): (Self::Fa<A>, Self::Fa<B>)) -> Self::Fa<(A, B)> { fn tuple<A: 'a, B: 'a>((fa, fb): (Self::F<A>, Self::F<B>)) -> Self::F<(A, B)> {
(fa, fb) (fa, fb)
} }
} }
@ -57,23 +57,23 @@ impl<'a> ApplicativeTuple<'a> for SoloInstance {
impl<'a> ApplicativeSelect<'a> for SoloInstance {} impl<'a> ApplicativeSelect<'a> for SoloInstance {}
impl<'a> Applicative<'a> for SoloInstance { impl<'a> Applicative<'a> for SoloInstance {
fn discard_first<A: 'a, B: 'a>(fa: Self::Fa<A>, fb: Self::Fa<B>) -> Self::Fa<B> { fn discard_first<A: 'a, B: 'a>(fa: Self::F<A>, fb: Self::F<B>) -> Self::F<B> {
drop(fa); drop(fa);
fb fb
} }
fn discard_second<A: 'a, B: 'a>(fa: Self::Fa<A>, fb: Self::Fa<B>) -> Self::Fa<A> { fn discard_second<A: 'a, B: 'a>(fa: Self::F<A>, fb: Self::F<B>) -> Self::F<A> {
drop(fb); drop(fb);
fa fa
} }
} }
impl<'a> Monad<'a> for SoloInstance { impl<'a> Monad<'a> for SoloInstance {
fn bind<A: 'a, B: 'a>(fa: Self::Fa<A>, f: impl 'a + FnOnce(A) -> Self::Fa<B>) -> Self::Fa<B> { fn bind<A: 'a, B: 'a>(fa: Self::F<A>, f: impl 'a + FnOnce(A) -> Self::F<B>) -> Self::F<B> {
f(fa) f(fa)
} }
fn iterate<B: 'a>(mut f: impl Iterative<'a, T = Self, B = B>) -> Self::Fa<B> { fn iterate<B: 'a>(mut f: impl Iterative<'a, T = Self, B = B>) -> Self::F<B> {
loop { loop {
match f.next() { match f.next() {
ControlFlow::Continue(next_f) => f = next_f, ControlFlow::Continue(next_f) => f = next_f,
@ -82,23 +82,23 @@ impl<'a> Monad<'a> for SoloInstance {
} }
} }
fn join<A: 'a>(ffa: Self::Fa<Self::Fa<A>>) -> Self::Fa<A> { fn join<A: 'a>(ffa: Self::F<Self::F<A>>) -> Self::F<A> {
ffa ffa
} }
} }
impl<'a> LocalFunctor<'a> for SoloInstance { impl<'a> LocalFunctor<'a> for SoloInstance {
fn unstuff<A: 'a, B: 'a>(state: Self::Fa<ControlFlow<B, A>>) -> ControlFlow<Self::Fa<B>, A> { fn unstuff<A: 'a, B: 'a>(state: Self::F<ControlFlow<B, A>>) -> ControlFlow<Self::F<B>, A> {
state state
} }
fn stuff<A: 'a, T: Pure<'a>>(fa: Self::Fa<T::Fa<A>>) -> T::Fa<Self::Fa<A>> { fn stuff<A: 'a, T: Pure<'a>>(fa: Self::F<T::F<A>>) -> T::F<Self::F<A>> {
fa fa
} }
} }
impl<'a> Fail<'a, std::convert::Infallible> for SoloInstance { impl<'a> Fail<'a, std::convert::Infallible> for SoloInstance {
fn fail<A: 'a>(e: std::convert::Infallible) -> Self::Fa<A> { fn fail<A: 'a>(e: std::convert::Infallible) -> Self::F<A> {
match e {} match e {}
} }
} }

View File

@ -119,16 +119,16 @@ impl<'a, A: 'a> From<A> for Stackless<'a, A> {
pub struct StacklessInstance; pub struct StacklessInstance;
impl WeakFunctor for StacklessInstance { impl WeakFunctorAny for StacklessInstance {
type F<'a, A: 'a> = Stackless<'a, A>; type FAny<'a, A: 'a> = Stackless<'a, A>;
} }
impl<'a> Functor<'a> for StacklessInstance { impl<'a> Functor<'a> for StacklessInstance {
fn fmap<A: 'a, B: 'a>(f: impl 'a + FnOnce(A) -> B, fa: Self::Fa<A>) -> Self::Fa<B> { fn fmap<A: 'a, B: 'a>(f: impl 'a + FnOnce(A) -> B, fa: Self::F<A>) -> Self::F<B> {
fa.map(f) fa.map(f)
} }
fn replace<A: 'a, B: 'a>(fa: Self::Fa<A>, b: B) -> Self::Fa<B> { fn replace<A: 'a, B: 'a>(fa: Self::F<A>, b: B) -> Self::F<B> {
Stackless(Box::new(|takesb| { Stackless(Box::new(|takesb| {
Some(EvalTree::Composite( Some(EvalTree::Composite(
Box::new(EvalTree::Atom(Box::new(move || fa.call(drop)))), Box::new(EvalTree::Atom(Box::new(move || fa.call(drop)))),
@ -142,13 +142,13 @@ impl<'a> Functor<'a> for StacklessInstance {
} }
impl<'a> Pure<'a> for StacklessInstance { impl<'a> Pure<'a> for StacklessInstance {
fn pure<A: 'a>(a: A) -> Self::Fa<A> { fn pure<A: 'a>(a: A) -> Self::F<A> {
Stackless::from(a) Stackless::from(a)
} }
} }
impl<'a> ApplicativeSeq<'a> for StacklessInstance { impl<'a> ApplicativeSeq<'a> for StacklessInstance {
fn seq<A: 'a, B: 'a>(ff: Self::Fa<impl 'a + FnOnce(A) -> B>, fa: Self::Fa<A>) -> Self::Fa<B> { fn seq<A: 'a, B: 'a>(ff: Self::F<impl 'a + FnOnce(A) -> B>, fa: Self::F<A>) -> Self::F<B> {
ff.bind(|f| fa.map(f)) ff.bind(|f| fa.map(f))
} }
} }
@ -156,15 +156,15 @@ impl<'a> ApplicativeSeq<'a> for StacklessInstance {
impl<'a> ApplicativeLA2<'a> for StacklessInstance { impl<'a> ApplicativeLA2<'a> for StacklessInstance {
fn la2<A: 'a, B: 'a, C: 'a>( fn la2<A: 'a, B: 'a, C: 'a>(
f: impl 'a + FnOnce(A, B) -> C, f: impl 'a + FnOnce(A, B) -> C,
fa: Self::Fa<A>, fa: Self::F<A>,
fb: Self::Fa<B>, fb: Self::F<B>,
) -> Self::Fa<C> { ) -> Self::F<C> {
Self::_la2_via_seq(f, fa, fb) Self::_la2_via_seq(f, fa, fb)
} }
} }
impl<'a> ApplicativeTuple<'a> for StacklessInstance { impl<'a> ApplicativeTuple<'a> for StacklessInstance {
fn tuple<A: 'a, B: 'a>((fa, fb): (Self::Fa<A>, Self::Fa<B>)) -> Self::Fa<(A, B)> { fn tuple<A: 'a, B: 'a>((fa, fb): (Self::F<A>, Self::F<B>)) -> Self::F<(A, B)> {
Self::_tuple_via_la2((fa, fb)) Self::_tuple_via_la2((fa, fb))
} }
} }
@ -172,7 +172,7 @@ impl<'a> ApplicativeTuple<'a> for StacklessInstance {
impl<'a> ApplicativeSelect<'a> for StacklessInstance {} impl<'a> ApplicativeSelect<'a> for StacklessInstance {}
impl<'a> Applicative<'a> for StacklessInstance { impl<'a> Applicative<'a> for StacklessInstance {
fn discard_first<A: 'a, B: 'a>(fa: Self::Fa<A>, fb: Self::Fa<B>) -> Self::Fa<B> { fn discard_first<A: 'a, B: 'a>(fa: Self::F<A>, fb: Self::F<B>) -> Self::F<B> {
Stackless(Box::new(|takesb| { Stackless(Box::new(|takesb| {
Some(EvalTree::Composite( Some(EvalTree::Composite(
Box::new(EvalTree::Atom(Box::new(|| fa.call(drop)))), Box::new(EvalTree::Atom(Box::new(|| fa.call(drop)))),
@ -181,7 +181,7 @@ impl<'a> Applicative<'a> for StacklessInstance {
})) }))
} }
fn discard_second<A: 'a, B: 'a>(fa: Self::Fa<A>, fb: Self::Fa<B>) -> Self::Fa<A> { fn discard_second<A: 'a, B: 'a>(fa: Self::F<A>, fb: Self::F<B>) -> Self::F<A> {
Stackless(Box::new(|takesa| { Stackless(Box::new(|takesa| {
Some(EvalTree::Composite( Some(EvalTree::Composite(
Box::new(EvalTree::Atom(Box::new(|| fa.0(takesa)))), Box::new(EvalTree::Atom(Box::new(|| fa.0(takesa)))),
@ -192,11 +192,11 @@ impl<'a> Applicative<'a> for StacklessInstance {
} }
impl<'a> Monad<'a> for StacklessInstance { impl<'a> Monad<'a> for StacklessInstance {
fn bind<A: 'a, B: 'a>(fa: Self::Fa<A>, f: impl 'a + FnOnce(A) -> Self::Fa<B>) -> Self::Fa<B> { fn bind<A: 'a, B: 'a>(fa: Self::F<A>, f: impl 'a + FnOnce(A) -> Self::F<B>) -> Self::F<B> {
fa.bind(f) fa.bind(f)
} }
fn iterate<B: 'a>(f: impl Iterative<'a, T = Self, B = B>) -> Self::Fa<B> { fn iterate<B: 'a>(f: impl Iterative<'a, T = Self, B = B>) -> Self::F<B> {
Self::pure(()).bind(move |_| { Self::pure(()).bind(move |_| {
f.next().bind(|state| match state { f.next().bind(|state| match state {
ControlFlow::Continue(next_f) => Self::iterate(next_f), ControlFlow::Continue(next_f) => Self::iterate(next_f),
@ -205,7 +205,7 @@ impl<'a> Monad<'a> for StacklessInstance {
}) })
} }
fn join<A: 'a>(ffa: Self::Fa<Self::Fa<A>>) -> Self::Fa<A> { fn join<A: 'a>(ffa: Self::F<Self::F<A>>) -> Self::F<A> {
Stackless(Box::new(|takesa| { Stackless(Box::new(|takesa| {
let lcell = Rc::new(Cell::new(None)); let lcell = Rc::new(Cell::new(None));
let rcell = lcell.clone(); let rcell = lcell.clone();
@ -231,15 +231,15 @@ mod stackless_test {
impl<'a> tests::Eqr<'a> for T { impl<'a> tests::Eqr<'a> for T {
fn eqr<A: PartialEq + std::fmt::Debug + 'a>( fn eqr<A: PartialEq + std::fmt::Debug + 'a>(
name: &'a str, name: &'a str,
left: Self::Fa<A>, left: Self::F<A>,
right: Self::Fa<A>, right: Self::F<A>,
) -> tests::R { ) -> tests::R {
tests::eqr(name, left.evaluate(), right.evaluate()) tests::eqr(name, left.evaluate(), right.evaluate())
} }
} }
impl<'a> test_suite::FunctorTestSuite<'a> for T { impl<'a> test_suite::FunctorTestSuite<'a> for T {
fn sample<A: 'a, F: FnMut(&'a dyn Fn(A) -> Self::Fa<A>)>(mut f: F) { fn sample<A: 'a, F: FnMut(&'a dyn Fn(A) -> Self::F<A>)>(mut f: F) {
f(&|a| a.into()); f(&|a| a.into());
} }
} }

View File

@ -9,16 +9,16 @@ use crate::func::*;
pub struct TryFutureInstance<E>(E); pub struct TryFutureInstance<E>(E);
impl<E> WeakFunctor for TryFutureInstance<E> { impl<E> WeakFunctorAny for TryFutureInstance<E> {
type F<'a, A: 'a> = Pin<Box<dyn 'a + Future<Output = Result<A, E>>>> where Self: 'a; type FAny<'a, A: 'a> = Pin<Box<dyn 'a + Future<Output = Result<A, E>>>> where Self: 'a;
} }
impl<'a, E: 'a> Functor<'a> for TryFutureInstance<E> { impl<'a, E: 'a> Functor<'a> for TryFutureInstance<E> {
fn fmap<A: 'a, B: 'a>(f: impl 'a + FnOnce(A) -> B, fa: Self::Fa<A>) -> Self::Fa<B> { fn fmap<A: 'a, B: 'a>(f: impl 'a + FnOnce(A) -> B, fa: Self::F<A>) -> Self::F<B> {
Box::pin(async { Ok(f(fa.await?)) }) Box::pin(async { Ok(f(fa.await?)) })
} }
fn replace<A: 'a, B: 'a>(fa: Self::Fa<A>, b: B) -> Self::Fa<B> { fn replace<A: 'a, B: 'a>(fa: Self::F<A>, b: B) -> Self::F<B> {
Box::pin(async { Box::pin(async {
fa.await?; fa.await?;
Ok(b) Ok(b)
@ -27,13 +27,13 @@ impl<'a, E: 'a> Functor<'a> for TryFutureInstance<E> {
} }
impl<'a, E: 'a> Pure<'a> for TryFutureInstance<E> { impl<'a, E: 'a> Pure<'a> for TryFutureInstance<E> {
fn pure<A: 'a>(a: A) -> Self::Fa<A> { fn pure<A: 'a>(a: A) -> Self::F<A> {
Box::pin(async { Ok(a) }) Box::pin(async { Ok(a) })
} }
} }
impl<'a, E: 'a> ApplicativeSeq<'a> for TryFutureInstance<E> { impl<'a, E: 'a> ApplicativeSeq<'a> for TryFutureInstance<E> {
fn seq<A: 'a, B: 'a>(ff: Self::Fa<impl 'a + FnOnce(A) -> B>, fa: Self::Fa<A>) -> Self::Fa<B> { fn seq<A: 'a, B: 'a>(ff: Self::F<impl 'a + FnOnce(A) -> B>, fa: Self::F<A>) -> Self::F<B> {
Box::pin(async { Box::pin(async {
let (f, a) = try_join!(ff, fa)?; let (f, a) = try_join!(ff, fa)?;
Ok(f(a)) Ok(f(a))
@ -44,9 +44,9 @@ impl<'a, E: 'a> ApplicativeSeq<'a> for TryFutureInstance<E> {
impl<'a, E: 'a> ApplicativeLA2<'a> for TryFutureInstance<E> { impl<'a, E: 'a> ApplicativeLA2<'a> for TryFutureInstance<E> {
fn la2<A: 'a, B: 'a, C: 'a>( fn la2<A: 'a, B: 'a, C: 'a>(
f: impl 'a + FnOnce(A, B) -> C, f: impl 'a + FnOnce(A, B) -> C,
fa: Self::Fa<A>, fa: Self::F<A>,
fb: Self::Fa<B>, fb: Self::F<B>,
) -> Self::Fa<C> { ) -> Self::F<C> {
Box::pin(async { Box::pin(async {
let (a, b) = try_join!(fa, fb)?; let (a, b) = try_join!(fa, fb)?;
Ok(f(a, b)) Ok(f(a, b))
@ -55,13 +55,13 @@ impl<'a, E: 'a> ApplicativeLA2<'a> for TryFutureInstance<E> {
} }
impl<'a, E: 'a> ApplicativeTuple<'a> for TryFutureInstance<E> { impl<'a, E: 'a> ApplicativeTuple<'a> for TryFutureInstance<E> {
fn tuple<A: 'a, B: 'a>((fa, fb): (Self::Fa<A>, Self::Fa<B>)) -> Self::Fa<(A, B)> { fn tuple<A: 'a, B: 'a>((fa, fb): (Self::F<A>, Self::F<B>)) -> Self::F<(A, B)> {
Box::pin(async { try_join!(fa, fb) }) Box::pin(async { try_join!(fa, fb) })
} }
} }
impl<'a, E: 'a> ApplicativeSelect<'a> for TryFutureInstance<E> { impl<'a, E: 'a> ApplicativeSelect<'a> for TryFutureInstance<E> {
fn select<A: 'a, B: 'a>(fa: Self::Fa<A>, fb: Self::Fa<B>) -> SelectedWrapped<'a, A, B, Self> { fn select<A: 'a, B: 'a>(fa: Self::F<A>, fb: Self::F<B>) -> SelectedWrapped<'a, A, B, Self> {
Box::pin(async { Box::pin(async {
match try_select(fa, fb).await { match try_select(fa, fb).await {
Ok(Either::Left((a, fb))) => Ok(Selected::A(a, fb)), Ok(Either::Left((a, fb))) => Ok(Selected::A(a, fb)),
@ -74,21 +74,21 @@ impl<'a, E: 'a> ApplicativeSelect<'a> for TryFutureInstance<E> {
} }
impl<'a, E: 'a> Applicative<'a> for TryFutureInstance<E> { impl<'a, E: 'a> Applicative<'a> for TryFutureInstance<E> {
fn discard_first<A: 'a, B: 'a>(fa: Self::Fa<A>, fb: Self::Fa<B>) -> Self::Fa<B> { fn discard_first<A: 'a, B: 'a>(fa: Self::F<A>, fb: Self::F<B>) -> Self::F<B> {
Box::pin(async { Ok(try_join!(fa, fb)?.1) }) Box::pin(async { Ok(try_join!(fa, fb)?.1) })
} }
fn discard_second<A: 'a, B: 'a>(fa: Self::Fa<A>, fb: Self::Fa<B>) -> Self::Fa<A> { fn discard_second<A: 'a, B: 'a>(fa: Self::F<A>, fb: Self::F<B>) -> Self::F<A> {
Box::pin(async { Ok(try_join!(fa, fb)?.0) }) Box::pin(async { Ok(try_join!(fa, fb)?.0) })
} }
} }
impl<'a, E: 'a> Monad<'a> for TryFutureInstance<E> { impl<'a, E: 'a> Monad<'a> for TryFutureInstance<E> {
fn bind<A: 'a, B: 'a>(fa: Self::Fa<A>, f: impl 'a + FnOnce(A) -> Self::Fa<B>) -> Self::Fa<B> { fn bind<A: 'a, B: 'a>(fa: Self::F<A>, f: impl 'a + FnOnce(A) -> Self::F<B>) -> Self::F<B> {
Box::pin(async { f(fa.await?).await }) Box::pin(async { f(fa.await?).await })
} }
fn iterate<B: 'a>(mut f: impl Iterative<'a, T = Self, B = B>) -> Self::Fa<B> { fn iterate<B: 'a>(mut f: impl Iterative<'a, T = Self, B = B>) -> Self::F<B> {
Box::pin(async move { Box::pin(async move {
loop { loop {
match f.next().await? { match f.next().await? {
@ -99,7 +99,7 @@ impl<'a, E: 'a> Monad<'a> for TryFutureInstance<E> {
}) })
} }
fn join<A: 'a>(ffa: Self::Fa<Self::Fa<A>>) -> Self::Fa<A> { fn join<A: 'a>(ffa: Self::F<Self::F<A>>) -> Self::F<A> {
Box::pin(async { ffa.await?.await }) Box::pin(async { ffa.await?.await })
} }
} }
@ -107,17 +107,17 @@ impl<'a, E: 'a> Monad<'a> for TryFutureInstance<E> {
impl<'a, E: 'a + Clone> SharedFunctor<'a> for TryFutureInstance<E> { impl<'a, E: 'a + Clone> SharedFunctor<'a> for TryFutureInstance<E> {
type Shared<A: 'a + Clone> = Shared<Pin<Box<dyn 'a + Future<Output = Result<A, E>>>>>; type Shared<A: 'a + Clone> = Shared<Pin<Box<dyn 'a + Future<Output = Result<A, E>>>>>;
fn share<A: 'a + Clone>(fa: Self::Fa<A>) -> Self::Shared<A> { fn share<A: 'a + Clone>(fa: Self::F<A>) -> Self::Shared<A> {
fa.shared() fa.shared()
} }
fn unshare<A: 'a + Clone>(sa: Self::Shared<A>) -> Self::Fa<A> { fn unshare<A: 'a + Clone>(sa: Self::Shared<A>) -> Self::F<A> {
Box::pin(sa) Box::pin(sa)
} }
} }
impl<'a, E: 'a> Fail<'a, E> for TryFutureInstance<E> { impl<'a, E: 'a> Fail<'a, E> for TryFutureInstance<E> {
fn fail<A: 'a>(e: E) -> Self::Fa<A> { fn fail<A: 'a>(e: E) -> Self::F<A> {
Box::pin(async { Err(e) }) Box::pin(async { Err(e) })
} }
} }

View File

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

View File

@ -26,8 +26,8 @@ impl R {
} }
} }
pub trait Eqr<'a>: WeakFunctorA<'a> { pub trait Eqr<'a>: WeakFunctor<'a> {
fn eqr<A: PartialEq + Debug + 'a>(name: &'a str, left: Self::Fa<A>, right: Self::Fa<A>) -> R; fn eqr<A: PartialEq + Debug + 'a>(name: &'a str, left: Self::F<A>, right: Self::F<A>) -> R;
} }
pub fn eqr<T: PartialEq + Debug>(name: &str, left: T, right: T) -> R { pub fn eqr<T: PartialEq + Debug>(name: &str, left: T, right: T) -> R {
@ -88,7 +88,7 @@ impl AddAssign<R> for R {
} }
pub fn fmap_respects_identity<'a, T: Functor<'a> + Eqr<'a>, A: 'a + Debug + PartialEq>( pub fn fmap_respects_identity<'a, T: Functor<'a> + Eqr<'a>, A: 'a + Debug + PartialEq>(
fa0: impl Fn() -> T::Fa<A>, fa0: impl Fn() -> T::F<A>,
) -> R { ) -> R {
T::eqr("identity: fmap id == id", T::fmap(|a| a, fa0()), fa0()) T::eqr("identity: fmap id == id", T::fmap(|a| a, fa0()), fa0())
} }
@ -102,7 +102,7 @@ pub fn fmap_respects_composition<
>( >(
f: impl 'a + Copy + Fn(B) -> C, f: impl 'a + Copy + Fn(B) -> C,
g: impl 'a + Copy + Fn(A) -> B, g: impl 'a + Copy + Fn(A) -> B,
fa0: impl Fn() -> T::Fa<A>, fa0: impl Fn() -> T::F<A>,
) -> R { ) -> R {
T::eqr( T::eqr(
"composition: fmap (f . g) == fmap f . fmap g", "composition: fmap (f . g) == fmap f . fmap g",
@ -112,7 +112,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 + Debug + PartialEq>(
fa0: impl Fn() -> T::Fa<A>, fa0: impl Fn() -> T::F<A>,
) -> R { ) -> R {
T::eqr( T::eqr(
"identity: pure id <*> v = v", "identity: pure id <*> v = v",
@ -130,9 +130,9 @@ pub fn seq_respects_composition<
F: 'a + Fn(B) -> C, F: 'a + Fn(B) -> C,
G: 'a + Fn(A) -> B, G: 'a + Fn(A) -> B,
>( >(
ff0: impl Fn() -> T::Fa<F>, ff0: impl Fn() -> T::F<F>,
fg0: impl Fn() -> T::Fa<G>, fg0: impl Fn() -> T::F<G>,
fa0: impl Fn() -> T::Fa<A>, fa0: impl Fn() -> T::F<A>,
) -> R { ) -> R {
T::eqr( T::eqr(
"composition: pure (.) <*> u <*> v <*> w = u <*> (v <*> w)", "composition: pure (.) <*> u <*> v <*> w = u <*> (v <*> w)",
@ -165,7 +165,7 @@ pub fn seq_respects_interchange<
B: 'a + Debug + PartialEq, B: 'a + Debug + PartialEq,
F: 'a + Fn(A) -> B, F: 'a + Fn(A) -> B,
>( >(
ff0: impl Fn() -> T::Fa<F>, ff0: impl Fn() -> T::F<F>,
a0: impl 'a + Fn() -> A, a0: impl 'a + Fn() -> A,
) -> R { ) -> R {
T::eqr( T::eqr(
@ -182,8 +182,8 @@ pub fn seq_can_be_expressed_via_la2<
B: 'a + Debug + PartialEq, B: 'a + Debug + PartialEq,
F: 'a + Fn(A) -> B, F: 'a + Fn(A) -> B,
>( >(
ff0: impl Fn() -> T::Fa<F>, ff0: impl Fn() -> T::F<F>,
fa0: impl Fn() -> T::Fa<A>, fa0: impl Fn() -> T::F<A>,
) -> R { ) -> R {
T::eqr( T::eqr(
"seq via la2: (<*>) = liftA2 id", "seq via la2: (<*>) = liftA2 id",
@ -199,7 +199,7 @@ pub fn fmap_can_be_expressed_via_seq<
B: 'a + Debug + PartialEq, B: 'a + Debug + PartialEq,
>( >(
f: impl 'a + Copy + Fn(A) -> B, f: impl 'a + Copy + Fn(A) -> B,
fa0: impl Fn() -> T::Fa<A>, fa0: impl Fn() -> T::F<A>,
) -> R { ) -> R {
T::eqr( T::eqr(
"fmap via seq: fmap f x = pure f <*> x", "fmap via seq: fmap f x = pure f <*> x",
@ -214,8 +214,8 @@ pub fn discard_can_be_expressed_via_seq_or_la2<
A: 'a, A: 'a,
B: 'a + Debug + PartialEq, B: 'a + Debug + PartialEq,
>( >(
fa0: impl 'a + Fn() -> T::Fa<A>, fa0: impl 'a + Fn() -> T::F<A>,
fb0: impl 'a + Fn() -> T::Fa<B>, fb0: impl 'a + Fn() -> T::F<B>,
) -> R { ) -> R {
T::eqr( T::eqr(
"discard via seq: u *> v = (id <$ u) <*> v", "discard via seq: u *> v = (id <$ u) <*> v",
@ -229,7 +229,7 @@ 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>( 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<B>, f: impl 'a + Fn(A) -> T::F<B>,
a0: impl Fn() -> A, a0: impl Fn() -> A,
) -> R { ) -> R {
T::eqr( T::eqr(
@ -240,7 +240,7 @@ 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 + Debug + PartialEq>(
fa0: impl Fn() -> T::Fa<A>, fa0: impl Fn() -> T::F<A>,
) -> R { ) -> R {
T::eqr( T::eqr(
"right identity: m >>= bind = m", "right identity: m >>= bind = m",
@ -250,9 +250,9 @@ 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>( 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<C>, f: impl 'a + Clone + Fn(B) -> T::F<C>,
g: impl 'a + Clone + Fn(A) -> T::Fa<B>, g: impl 'a + Clone + Fn(A) -> T::F<B>,
fa0: impl 'a + Fn() -> T::Fa<A>, fa0: impl 'a + Fn() -> T::F<A>,
) -> R { ) -> R {
T::eqr( T::eqr(
r"associativity: m >>= (\x -> k x >>= h) = (m >>= k) >>= h", r"associativity: m >>= (\x -> k x >>= h) = (m >>= k) >>= h",
@ -268,8 +268,8 @@ pub fn seq_can_be_expressed_via_bind<
B: 'a + Debug + PartialEq, B: 'a + Debug + PartialEq,
F: 'a + Fn(A) -> B, F: 'a + Fn(A) -> B,
>( >(
ff0: impl Fn() -> T::Fa<F>, ff0: impl Fn() -> T::F<F>,
fa0: impl 'a + Fn() -> T::Fa<A>, fa0: impl 'a + Fn() -> T::F<A>,
) -> R { ) -> R {
T::eqr( T::eqr(
r"seq via bind: m1 <*> m2 = m1 >>= (\x1 -> m2 >>= (\x2 -> pure (x1 x2)))", r"seq via bind: m1 <*> m2 = m1 >>= (\x1 -> m2 >>= (\x2 -> pure (x1 x2)))",
@ -285,7 +285,7 @@ pub fn fmap_can_be_expressed_via_bind<
B: 'a + Debug + PartialEq, B: 'a + Debug + PartialEq,
>( >(
f: impl 'a + Copy + Fn(A) -> B, f: impl 'a + Copy + Fn(A) -> B,
fa0: impl 'a + Fn() -> T::Fa<A>, fa0: impl 'a + Fn() -> T::F<A>,
) -> R { ) -> R {
T::eqr( T::eqr(
"fmap via bind: fmap f xs = xs >>= return . f", "fmap via bind: fmap f xs = xs >>= return . f",

View File

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

View File

@ -13,15 +13,15 @@ use crate::rstd::typeless::*;
pub struct NoDiagnostic; pub struct NoDiagnostic;
impl<'a, T: Monad<'a>> Diagnostic<'a, T> for NoDiagnostic { impl<'a, T: Monad<'a>> Diagnostic<'a, T> for NoDiagnostic {
fn after<'b, A>(fa: T::Fa<A>, _event: impl 'b + FnOnce() -> String) -> T::Fa<A> { fn after<'b, A>(fa: T::F<A>, _event: impl 'b + FnOnce() -> String) -> T::F<A> {
fa fa
} }
fn before<'b, A>(fa: T::Fa<A>, _event: impl 'b + FnOnce() -> String) -> T::Fa<A> { fn before<'b, A>(fa: T::F<A>, _event: impl 'b + FnOnce() -> String) -> T::F<A> {
fa fa
} }
fn wrapped<'b, A>(fa: T::Fa<A>, _event: impl 'b + FnOnce() -> String) -> T::Fa<A> { fn wrapped<'b, A>(fa: T::F<A>, _event: impl 'b + FnOnce() -> String) -> T::F<A> {
fa fa
} }
} }