WeakFunctorA
as main; remove CovariantFunctor
This commit is contained in:
parent
1772ca5186
commit
d3d249fe96
@ -1 +1 @@
|
|||||||
Subproject commit f1dd33d61f7d1ce9c1d428ff0d75fb3efb2bb340
|
Subproject commit b96a072b3a80e689cb99dc6e9922add0d6d93c87
|
@ -39,22 +39,3 @@ fn add_clone_bounds(mut generics: 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)
|
|
||||||
}
|
|
||||||
|
@ -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::F<'a, ()> {
|
) -> T::Fa<()> {
|
||||||
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::F<'a, ()> {
|
) -> T::Fa<()> {
|
||||||
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::F<'a, ()> {
|
) -> T::Fa<()> {
|
||||||
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(()),
|
||||||
|
@ -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::F<'a, ()> {
|
fn on_l(self, (t_subl, t_subr, k_sub): Split<'a, T, A, D>) -> T::Fa<()> {
|
||||||
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::F<'a, ()> {
|
fn on_e(self, (t_subl, t_subr, k_sub): Split<'a, T, A, D>) -> T::Fa<()> {
|
||||||
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::F<'a, ()> {
|
fn on_r(self, (t_subl, t_subr, k_sub): Split<'a, T, A, D>) -> T::Fa<()> {
|
||||||
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::F<'a, ()> {
|
fn test(self) -> T::Fa<()> {
|
||||||
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::F<'a, ()> {
|
) -> T::Fa<()> {
|
||||||
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::F<'a, ()> {
|
) -> T::Fa<()> {
|
||||||
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::F<'a, ()> {
|
) -> T::Fa<()> {
|
||||||
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(()),
|
||||||
|
114
src/func.rs
114
src/func.rs
@ -21,7 +21,7 @@ pub mod tests;
|
|||||||
|
|
||||||
pub use std::ops::ControlFlow;
|
pub use std::ops::ControlFlow;
|
||||||
|
|
||||||
pub use radn_derive::{CovariantFunctor, SharedFunctor};
|
pub use radn_derive::SharedFunctor;
|
||||||
|
|
||||||
pub use self::applicative_select::{
|
pub use self::applicative_select::{
|
||||||
ApplicativeSelect, ApplicativeSelectExt, Selected, SelectedWrapped,
|
ApplicativeSelect, ApplicativeSelectExt, Selected, SelectedWrapped,
|
||||||
@ -31,9 +31,6 @@ pub use self::controlflow::{Iterative, IterativeWrapped};
|
|||||||
#[cfg(doc)]
|
#[cfg(doc)]
|
||||||
use self::instances::stackless::StacklessInstance;
|
use self::instances::stackless::StacklessInstance;
|
||||||
|
|
||||||
/// Part of Haskell's `Functor f` responsible for having `f a`.
|
|
||||||
///
|
|
||||||
/// <https://hackage.haskell.org/package/base-4.18.0.0/docs/Data-Functor.html>
|
|
||||||
pub trait WeakFunctor {
|
pub trait WeakFunctor {
|
||||||
/// Type of the wrapped value.
|
/// Type of the wrapped value.
|
||||||
type F<'a, A: 'a>: 'a
|
type F<'a, A: 'a>: 'a
|
||||||
@ -41,6 +38,9 @@ pub trait WeakFunctor {
|
|||||||
Self: 'a;
|
Self: '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>
|
||||||
pub trait WeakFunctorA<'a>: 'a {
|
pub trait WeakFunctorA<'a>: 'a {
|
||||||
type Fa<A: 'a>: 'a;
|
type Fa<A: 'a>: 'a;
|
||||||
}
|
}
|
||||||
@ -53,59 +53,20 @@ pub type Wrap<'a, A, T> = <T as WeakFunctorA<'a>>::Fa<A>;
|
|||||||
|
|
||||||
/// Rust-specific implementation of [`Functor`], respecting `move` semantics.
|
/// 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<A>;
|
|
||||||
/// }
|
|
||||||
///
|
|
||||||
/// 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<A>;
|
|
||||||
/// }
|
|
||||||
///
|
|
||||||
/// 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()
|
|
||||||
/// }
|
|
||||||
/// }
|
|
||||||
/// ```
|
|
||||||
///
|
|
||||||
/// <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>: 'a + WeakFunctor {
|
pub trait Functor<'a>: WeakFunctorA<'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::F<'a, A>) -> Self::F<'a, B>;
|
fn fmap<A: 'a, B: 'a>(f: impl 'a + FnOnce(A) -> B, fa: Self::Fa<A>) -> Self::Fa<B>;
|
||||||
|
|
||||||
/// Equivalent of Haskell's `$>`/`<$`.
|
/// Equivalent of Haskell's `$>`/`<$`.
|
||||||
fn replace<A: 'a, B: 'a>(fa: Self::F<'a, A>, b: B) -> Self::F<'a, B> {
|
fn replace<A: 'a, B: 'a>(fa: Self::Fa<A>, b: B) -> Self::Fa<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::F<'a, A>) -> Self::F<'a, ()> {
|
fn void<A: 'a>(fa: Self::Fa<A>) -> Self::Fa<()> {
|
||||||
Self::replace(fa, ())
|
Self::replace(fa, ())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -113,16 +74,13 @@ pub trait Functor<'a>: 'a + WeakFunctor {
|
|||||||
/// 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::F<'a, A>;
|
fn pure<A: 'a>(a: A) -> Self::Fa<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>(
|
fn seq<A: 'a, B: 'a>(ff: Self::Fa<impl 'a + FnOnce(A) -> B>, fa: Self::Fa<A>) -> Self::Fa<B>;
|
||||||
ff: Self::F<'a, impl 'a + FnOnce(A) -> B>,
|
|
||||||
fa: Self::F<'a, A>,
|
|
||||||
) -> Self::F<'a, B>;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Part of [`Applicative`] responsible for Haskell's result combination `listA2`.
|
/// 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`.
|
/// 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::F<'a, A>,
|
fa: Self::Fa<A>,
|
||||||
fb: Self::F<'a, B>,
|
fb: Self::Fa<B>,
|
||||||
) -> Self::F<'a, C>;
|
) -> Self::Fa<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::F<'a, A>, Self::F<'a, B>)) -> Self::F<'a, (A, B)>;
|
fn tuple<A: 'a, B: 'a>(fab: (Self::Fa<A>, Self::Fa<B>)) -> Self::Fa<(A, B)>;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Equivalent of Haskell's `Applicative`.
|
/// Equivalent of Haskell's `Applicative`.
|
||||||
@ -149,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::F<'a, A>, fb: Self::F<'a, B>) -> Self::F<'a, B> {
|
fn discard_first<A: 'a, B: 'a>(fa: Self::Fa<A>, fb: Self::Fa<B>) -> Self::Fa<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::F<'a, A>, fb: Self::F<'a, B>) -> Self::F<'a, A> {
|
fn discard_second<A: 'a, B: 'a>(fa: Self::Fa<A>, fb: Self::Fa<B>) -> Self::Fa<A> {
|
||||||
Self::la2(|a, _| a, fa, fb)
|
Self::la2(|a, _| a, fa, fb)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -166,19 +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>(
|
fn bind<A: 'a, B: 'a>(fa: Self::Fa<A>, f: impl 'a + FnOnce(A) -> Self::Fa<B>) -> Self::Fa<B>;
|
||||||
fa: Self::F<'a, A>,
|
|
||||||
f: impl 'a + FnOnce(A) -> Self::F<'a, B>,
|
|
||||||
) -> Self::F<'a, 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::F<'a, B>;
|
fn iterate<B: 'a>(f: impl Iterative<'a, T = Self, B = B>) -> Self::Fa<B>;
|
||||||
|
|
||||||
/// Equivalent of Haskell's `join`.
|
/// Equivalent of Haskell's `join`.
|
||||||
fn join<A: 'a>(ffa: Self::F<'a, Self::F<'a, A>>) -> Self::F<'a, A> {
|
fn join<A: 'a>(ffa: Self::Fa<Self::Fa<A>>) -> Self::Fa<A> {
|
||||||
Self::bind(ffa, |fa| fa)
|
Self::bind(ffa, |fa| fa)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -190,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::F<'a, ControlFlow<B, A>>,
|
f: impl 'a + FnMut(A) -> Self::Fa<ControlFlow<B, A>>,
|
||||||
) -> Self::F<'a, B> {
|
) -> Self::Fa<B> {
|
||||||
Self::iterate(BindableMut::new(a, f))
|
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 {}
|
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>: 'a + WeakFunctor {
|
pub trait Fail<'a, E: 'a>: WeakFunctorA<'a> {
|
||||||
/// Equivalent of Haskell's `fail`.
|
/// Equivalent of Haskell's `fail`.
|
||||||
fn fail<A: 'a>(e: E) -> Self::F<'a, A>;
|
fn fail<A: 'a>(e: E) -> Self::Fa<A>;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Equivalent of Haskell's `MonadFail`. Auto-implemented for all [`Fail`]`+`[`Monad`].
|
/// 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 {}
|
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: WeakFunctor {
|
pub trait LocalFunctor<'a>: WeakFunctorA<'a> {
|
||||||
/// Extract iteration state, if successful.
|
/// Extract iteration state, if successful.
|
||||||
fn unstuff<'a, A: 'a, B: 'a>(
|
fn unstuff<A: 'a, B: 'a>(state: Self::Fa<ControlFlow<B, A>>) -> ControlFlow<Self::Fa<B>, A> {
|
||||||
state: Self::F<'a, ControlFlow<B, A>>,
|
|
||||||
) -> ControlFlow<Self::F<'a, B>, A>
|
|
||||||
where
|
|
||||||
Self: '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: 'a, T: Pure<'a>>(fa: Self::F<'a, T::F<'a, A>>) -> T::F<'a, Self::F<'a, A>>
|
fn stuff<A: 'a, T: Pure<'a>>(fa: Self::Fa<T::Fa<A>>) -> T::Fa<Self::Fa<A>>;
|
||||||
where
|
|
||||||
Self: '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.
|
||||||
@ -334,8 +282,10 @@ pub trait SharedFunctor: WeakFunctor {
|
|||||||
Self: 'a;
|
Self: 'a;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub trait CovariantFunctor: WeakFunctor {
|
pub trait SharedFunctorA<'a>: WeakFunctorA<'a> {
|
||||||
fn variate<'a: 'b, 'b, A: 'a>(fa: Self::F<'a, A>) -> Self::F<'b, A>
|
type SharedA<A: 'a + Clone>: 'a + Clone;
|
||||||
where
|
|
||||||
Self: 'a;
|
fn share<A: 'a + Clone>(fa: Self::Fa<A>) -> Self::SharedA<A>;
|
||||||
|
|
||||||
|
fn unshare<A: 'a + Clone>(sa: Self::SharedA<A>) -> Self::Fa<A>;
|
||||||
}
|
}
|
||||||
|
@ -1,17 +1,14 @@
|
|||||||
use super::*;
|
use super::*;
|
||||||
|
|
||||||
pub enum Selected<'a, A: 'a, B: 'a, T: ?Sized + 'a + WeakFunctor> {
|
pub enum Selected<'a, A: 'a, B: 'a, T: ?Sized + WeakFunctorA<'a>> {
|
||||||
A(A, T::F<'a, B>),
|
A(A, T::Fa<B>),
|
||||||
B(T::F<'a, A>, B),
|
B(T::Fa<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>(
|
fn select<A: 'a, B: 'a>(fa: Self::Fa<A>, fb: Self::Fa<B>) -> SelectedWrapped<'a, A, B, Self> {
|
||||||
fa: Self::F<'a, A>,
|
|
||||||
fb: Self::F<'a, B>,
|
|
||||||
) -> SelectedWrapped<'a, A, B, Self> {
|
|
||||||
Self::fmap(|a| Selected::A(a, fb), fa)
|
Self::fmap(|a| Selected::A(a, fb), fa)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -19,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::F<'a, A>,
|
fa: Self::Fa<A>,
|
||||||
fb: Self::F<'a, B>,
|
fb: Self::Fa<B>,
|
||||||
) -> Self::F<'a, C> {
|
) -> Self::Fa<C> {
|
||||||
Self::fmap(f, Self::select(fa, fb))
|
Self::fmap(f, Self::select(fa, fb))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -11,7 +11,7 @@ impl<C> WeakFunctor for ControlFlowInstance<C> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
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::F<'a, A>) -> Self::F<'a, B> {
|
fn fmap<A: 'a, B: 'a>(f: impl 'a + FnOnce(A) -> B, fa: Self::Fa<A>) -> Self::Fa<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,33 +20,23 @@ 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::F<'a, A> {
|
fn pure<A: 'a>(a: A) -> Self::Fa<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<
|
impl<'a, T: ?Sized + Functor<'a>, A: 'a, B: 'a, F: 'a + FnMut(A) -> T::Fa<ControlFlow<B, A>>>
|
||||||
'a,
|
BindableMut<T, A, B, F>
|
||||||
T: ?Sized + Functor<'a>,
|
|
||||||
A: 'a,
|
|
||||||
B: 'a,
|
|
||||||
F: 'a + FnMut(A) -> T::F<'a, ControlFlow<B, A>>,
|
|
||||||
> BindableMut<T, A, B, F>
|
|
||||||
{
|
{
|
||||||
pub fn new(a: A, f: F) -> Self {
|
pub fn new(a: A, f: F) -> Self {
|
||||||
BindableMut(a, f, PhantomData, PhantomData)
|
BindableMut(a, f, PhantomData, PhantomData)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<
|
impl<'a, T: ?Sized + Functor<'a>, A: 'a, B: 'a, F: 'a + FnMut(A) -> T::Fa<ControlFlow<B, A>>>
|
||||||
'a,
|
Iterative<'a> for BindableMut<T, A, B, F>
|
||||||
T: ?Sized + Functor<'a>,
|
|
||||||
A: 'a,
|
|
||||||
B: 'a,
|
|
||||||
F: 'a + FnMut(A) -> T::F<'a, ControlFlow<B, A>>,
|
|
||||||
> Iterative<'a> for BindableMut<T, A, B, F>
|
|
||||||
{
|
{
|
||||||
type B = B;
|
type B = B;
|
||||||
type T = T;
|
type T = T;
|
||||||
@ -74,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: 'a + ?Sized + WeakFunctor;
|
type T: ?Sized + WeakFunctorA<'a>;
|
||||||
/// Get next state.
|
/// Get next state.
|
||||||
fn next(self) -> IterativeWrapped<'a, Self>;
|
fn next(self) -> IterativeWrapped<'a, Self>;
|
||||||
}
|
}
|
||||||
|
@ -5,23 +5,23 @@ use super::*;
|
|||||||
/// Equivalent of Haskell's `fmap`. `function-function` equivalent of [Functor::fmap].
|
/// Equivalent of Haskell's `fmap`. `function-function` equivalent of [Functor::fmap].
|
||||||
pub fn fmap<'a, T: Functor<'a>, A: 'a, B: 'a>(
|
pub fn fmap<'a, T: Functor<'a>, A: 'a, B: 'a>(
|
||||||
f: impl 'a + FnOnce(A) -> B,
|
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)
|
move |fa| T::fmap(f, fa)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// 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::F<'a, B>,
|
f: impl 'a + FnOnce(A) -> T::Fa<B>,
|
||||||
) -> impl FnOnce(T::F<'a, A>) -> T::F<'a, B> {
|
) -> impl FnOnce(Wrap<'a, A, T>) -> Wrap<'a, B, T> {
|
||||||
move |fa| T::bind(fa, f)
|
move |fa| T::bind(fa, f)
|
||||||
}
|
}
|
||||||
|
|
||||||
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::F<'a, A>,
|
fa: Self::Fa<A>,
|
||||||
fb: Self::F<'a, B>,
|
fb: Self::Fa<B>,
|
||||||
) -> Self::F<'a, C> {
|
) -> Self::Fa<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::F<'a, impl 'a + FnOnce(A) -> B>,
|
ff: Self::Fa<impl 'a + FnOnce(A) -> B>,
|
||||||
fa: Self::F<'a, A>,
|
fa: Self::Fa<A>,
|
||||||
) -> Self::F<'a, B> {
|
) -> Self::Fa<B> {
|
||||||
Self::la2(|f, a| f(a), ff, 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 {}
|
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>(
|
fn _tuple_via_la2<A: 'a, B: 'a>((fa, fb): (Self::Fa<A>, Self::Fa<B>)) -> Self::Fa<(A, B)> {
|
||||||
(fa, fb): (Self::F<'a, A>, Self::F<'a, B>),
|
|
||||||
) -> Self::F<'a, (A, B)> {
|
|
||||||
Self::la2(|a, b| (a, b), fa, fb)
|
Self::la2(|a, b| (a, b), fa, fb)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2,26 +2,26 @@ use crate::func::*;
|
|||||||
|
|
||||||
pub struct CompositionInstance<U, V>(U, V);
|
pub struct CompositionInstance<U, V>(U, V);
|
||||||
|
|
||||||
impl<U: WeakFunctor, V: WeakFunctor> WeakFunctor for CompositionInstance<U, V> {
|
impl<'a, U: WeakFunctorA<'a>, V: WeakFunctorA<'a>> WeakFunctorA<'a> for CompositionInstance<U, V> {
|
||||||
type F<'a, A: 'a> = U::F<'a, V::F<'a, A>> where Self: 'a;
|
type Fa<A: 'a> = U::Fa<V::Fa<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::F<'a, A>) -> Self::F<'a, B> {
|
fn fmap<A: 'a, B: 'a>(f: impl 'a + FnOnce(A) -> B, fa: Self::Fa<A>) -> Self::Fa<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::F<'a, A>, b: B) -> Self::F<'a, B> {
|
fn replace<A: 'a, B: 'a>(fa: Self::Fa<A>, b: B) -> Self::Fa<B> {
|
||||||
U::fmap(|ua| V::replace(ua, b), fa)
|
U::fmap(|ua| V::replace(ua, b), fa)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn void<A: 'a>(fa: Self::F<'a, A>) -> Self::F<'a, ()> {
|
fn void<A: 'a>(fa: Self::Fa<A>) -> Self::Fa<()> {
|
||||||
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::F<'a, A> {
|
fn pure<A: 'a>(a: A) -> Self::Fa<A> {
|
||||||
U::pure(V::pure(a))
|
U::pure(V::pure(a))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -29,10 +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>(
|
fn seq<A: 'a, B: 'a>(ff: Self::Fa<impl 'a + FnOnce(A) -> B>, fa: Self::Fa<A>) -> Self::Fa<B> {
|
||||||
ff: Self::F<'a, impl 'a + FnOnce(A) -> B>,
|
|
||||||
fa: Self::F<'a, A>,
|
|
||||||
) -> Self::F<'a, B> {
|
|
||||||
U::la2(|uf, ua| V::seq(uf, ua), ff, 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<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::F<'a, A>,
|
fa: Self::Fa<A>,
|
||||||
fb: Self::F<'a, B>,
|
fb: Self::Fa<B>,
|
||||||
) -> Self::F<'a, C> {
|
) -> Self::Fa<C> {
|
||||||
U::la2(|ua, ub| V::la2(f, ua, ub), fa, fb)
|
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>
|
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::F<'a, A>, Self::F<'a, B>)) -> Self::F<'a, (A, B)> {
|
fn tuple<A: 'a, B: 'a>(fab: (Self::Fa<A>, Self::Fa<B>)) -> Self::Fa<(A, B)> {
|
||||||
U::fmap(V::tuple, U::tuple(fab))
|
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>
|
impl<'a, U: ApplicativeSelect<'a>, V: Functor<'a>> ApplicativeSelect<'a>
|
||||||
for CompositionInstance<U, V>
|
for CompositionInstance<U, V>
|
||||||
{
|
{
|
||||||
fn select<A: 'a, B: 'a>(
|
fn select<A: 'a, B: 'a>(fa: Self::Fa<A>, fb: Self::Fa<B>) -> SelectedWrapped<'a, A, B, Self> {
|
||||||
fa: Self::F<'a, A>,
|
|
||||||
fb: Self::F<'a, 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),
|
||||||
@ -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<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::F<'a, A>, fb: Self::F<'a, B>) -> Self::F<'a, B> {
|
fn discard_first<A: 'a, B: 'a>(fa: Self::Fa<A>, fb: Self::Fa<B>) -> Self::Fa<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::F<'a, A>, fb: Self::F<'a, B>) -> Self::F<'a, A> {
|
fn discard_second<A: 'a, B: 'a>(fa: Self::Fa<A>, fb: Self::Fa<B>) -> Self::Fa<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> 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>(
|
fn bind<A: 'a, B: 'a>(fa: Self::Fa<A>, f: impl 'a + FnOnce(A) -> Self::Fa<B>) -> Self::Fa<B> {
|
||||||
fa: Self::F<'a, A>,
|
|
||||||
f: impl 'a + FnOnce(A) -> Self::F<'a, B>,
|
|
||||||
) -> Self::F<'a, 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::F<'a, B> {
|
fn iterate<B: 'a>(f: impl Iterative<'a, T = Self, B = B>) -> Self::Fa<B> {
|
||||||
U::iterate(ComposedIterative(f))
|
U::iterate(ComposedIterative(f))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn join<A: 'a>(ffa: Self::F<'a, Self::F<'a, A>>) -> Self::F<'a, A> {
|
fn join<A: 'a>(ffa: Self::Fa<Self::Fa<A>>) -> Self::Fa<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))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -106,7 +97,7 @@ struct ComposedIterative<F>(F);
|
|||||||
impl<
|
impl<
|
||||||
'a,
|
'a,
|
||||||
U: Monad<'a>,
|
U: Monad<'a>,
|
||||||
V: Monad<'a> + LocalFunctor,
|
V: Monad<'a> + LocalFunctor<'a>,
|
||||||
F: Iterative<'a, T = CompositionInstance<U, V>>,
|
F: Iterative<'a, T = CompositionInstance<U, V>>,
|
||||||
> Iterative<'a> for ComposedIterative<F>
|
> Iterative<'a> for ComposedIterative<F>
|
||||||
{
|
{
|
||||||
@ -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<U, V>
|
for CompositionInstance<U, V>
|
||||||
{
|
{
|
||||||
fn fail<A: 'a>(e: E) -> Self::F<'a, A> {
|
fn fail<A: 'a>(e: E) -> Self::Fa<A> {
|
||||||
U::pure(V::fail(e))
|
U::pure(V::fail(e))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<U: LocalFunctor + for<'a> Functor<'a>, V: LocalFunctor> LocalFunctor
|
impl<'a, U: LocalFunctor<'a> + Functor<'a>, V: LocalFunctor<'a>> LocalFunctor<'a>
|
||||||
for CompositionInstance<U, V>
|
for CompositionInstance<U, V>
|
||||||
{
|
{
|
||||||
fn unstuff<'a, A: 'a, B: 'a>(
|
fn unstuff<A: 'a, B: 'a>(state: Self::Fa<ControlFlow<B, A>>) -> ControlFlow<Self::Fa<B>, A> {
|
||||||
state: Self::F<'a, ControlFlow<B, A>>,
|
|
||||||
) -> ControlFlow<Self::F<'a, B>, A>
|
|
||||||
where
|
|
||||||
Self: 'a,
|
|
||||||
{
|
|
||||||
U::unstuff(U::fmap(V::unstuff, state))
|
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>>
|
fn stuff<A: 'a, T: Pure<'a>>(fa: Self::Fa<T::Fa<A>>) -> T::Fa<Self::Fa<A>> {
|
||||||
where
|
|
||||||
Self: 'a,
|
|
||||||
{
|
|
||||||
U::stuff::<_, T>(U::fmap(V::stuff::<_, T>, fa))
|
U::stuff::<_, T>(U::fmap(V::stuff::<_, T>, fa))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<U: SharedFunctor + for<'a> Functor<'a>, V: SharedFunctor> SharedFunctor
|
impl<'a, U: SharedFunctorA<'a> + Functor<'a>, V: SharedFunctorA<'a>> SharedFunctorA<'a>
|
||||||
for CompositionInstance<U, V>
|
for CompositionInstance<U, V>
|
||||||
{
|
{
|
||||||
type Shared<'a, A: 'a + Clone> = U::Shared<'a, V::Shared<'a, A>>
|
type SharedA<A: 'a + Clone> = U::SharedA<V::SharedA<A>>;
|
||||||
where
|
|
||||||
Self: 'a;
|
|
||||||
|
|
||||||
fn share<'a, A: 'a + Clone>(fa: Self::F<'a, A>) -> Self::Shared<'a, A>
|
fn share<A: 'a + Clone>(fa: Self::Fa<A>) -> Self::SharedA<A> {
|
||||||
where
|
|
||||||
Self: 'a,
|
|
||||||
{
|
|
||||||
U::share(U::fmap(V::share, fa))
|
U::share(U::fmap(V::share, fa))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn unshare<'a, A: 'a + Clone>(sa: Self::Shared<'a, A>) -> Self::F<'a, A>
|
fn unshare<A: 'a + Clone>(sa: Self::SharedA<A>) -> Self::Fa<A> {
|
||||||
where
|
|
||||||
Self: 'a,
|
|
||||||
{
|
|
||||||
U::fmap(V::unshare, U::unshare(sa))
|
U::fmap(V::unshare, U::unshare(sa))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<U: CovariantFunctor + for<'a> Functor<'a>, V: CovariantFunctor> CovariantFunctor
|
|
||||||
for CompositionInstance<U, V>
|
|
||||||
{
|
|
||||||
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))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
@ -23,7 +23,7 @@ impl<A, E: Effect> WithEffect<A, E> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(SharedFunctor, CovariantFunctor)]
|
#[derive(SharedFunctor)]
|
||||||
pub struct EffectInstance<E>(E);
|
pub struct EffectInstance<E>(E);
|
||||||
|
|
||||||
impl<E> WeakFunctor for EffectInstance<E> {
|
impl<E> WeakFunctor for EffectInstance<E> {
|
||||||
@ -33,14 +33,14 @@ impl<E> WeakFunctor for EffectInstance<E> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
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::F<'a, A>) -> Self::F<'a, B> {
|
fn fmap<A: 'a, B: 'a>(f: impl 'a + FnOnce(A) -> B, fa: Self::Fa<A>) -> Self::Fa<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::F<'a, A>, b: B) -> Self::F<'a, B> {
|
fn replace<A: 'a, B: 'a>(fa: Self::Fa<A>, b: B) -> Self::Fa<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::F<'a, A> {
|
fn pure<A: 'a>(a: A) -> Self::Fa<A> {
|
||||||
WithEffect {
|
WithEffect {
|
||||||
value: a,
|
value: a,
|
||||||
effect: E::e_pure(),
|
effect: E::e_pure(),
|
||||||
@ -59,10 +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>(
|
fn seq<A: 'a, B: 'a>(ff: Self::Fa<impl 'a + FnOnce(A) -> B>, fa: Self::Fa<A>) -> Self::Fa<B>
|
||||||
ff: Self::F<'a, impl 'a + FnOnce(A) -> B>,
|
|
||||||
fa: Self::F<'a, A>,
|
|
||||||
) -> Self::F<'a, B>
|
|
||||||
where
|
where
|
||||||
Self: 'a,
|
Self: 'a,
|
||||||
{
|
{
|
||||||
@ -76,9 +73,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::F<'a, A>,
|
fa: Self::Fa<A>,
|
||||||
fb: Self::F<'a, B>,
|
fb: Self::Fa<B>,
|
||||||
) -> Self::F<'a, C>
|
) -> Self::Fa<C>
|
||||||
where
|
where
|
||||||
Self: 'a,
|
Self: 'a,
|
||||||
{
|
{
|
||||||
@ -90,7 +87,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::F<'a, A>, Self::F<'a, B>)) -> Self::F<'a, (A, B)> {
|
fn tuple<A: 'a, B: 'a>((fa, fb): (Self::Fa<A>, Self::Fa<B>)) -> Self::Fa<(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),
|
||||||
@ -101,7 +98,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::F<'a, A>, fb: Self::F<'a, B>) -> Self::F<'a, B> {
|
fn discard_first<A: 'a, B: 'a>(fa: Self::Fa<A>, fb: Self::Fa<B>) -> Self::Fa<B> {
|
||||||
drop(fa.value);
|
drop(fa.value);
|
||||||
WithEffect {
|
WithEffect {
|
||||||
value: fb.value,
|
value: fb.value,
|
||||||
@ -109,7 +106,7 @@ impl<'a, E: 'a + Effect> Applicative<'a> for EffectInstance<E> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn discard_second<A: 'a, B: 'a>(fa: Self::F<'a, A>, fb: Self::F<'a, B>) -> Self::F<'a, A> {
|
fn discard_second<A: 'a, B: 'a>(fa: Self::Fa<A>, fb: Self::Fa<B>) -> Self::Fa<A> {
|
||||||
drop(fb.value);
|
drop(fb.value);
|
||||||
WithEffect {
|
WithEffect {
|
||||||
value: fa.value,
|
value: fa.value,
|
||||||
@ -119,14 +116,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>(
|
fn bind<A: 'a, B: 'a>(fa: Self::Fa<A>, f: impl 'a + FnOnce(A) -> Self::Fa<B>) -> Self::Fa<B> {
|
||||||
fa: Self::F<'a, A>,
|
|
||||||
f: impl 'a + FnOnce(A) -> Self::F<'a, B>,
|
|
||||||
) -> Self::F<'a, 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::F<'a, B> {
|
fn iterate<B: 'a>(mut f: impl Iterative<'a, T = Self, B = B>) -> Self::Fa<B> {
|
||||||
let mut effect = E::e_pure();
|
let mut effect = E::e_pure();
|
||||||
loop {
|
loop {
|
||||||
let fa = f.next();
|
let fa = f.next();
|
||||||
@ -138,16 +132,13 @@ impl<'a, E: 'a + Effect> Monad<'a> for EffectInstance<E> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn join<A: 'a>(ffa: Self::F<'a, Self::F<'a, A>>) -> Self::F<'a, A> {
|
fn join<A: 'a>(ffa: Self::Fa<Self::Fa<A>>) -> Self::Fa<A> {
|
||||||
ffa.value.e_after(ffa.effect)
|
ffa.value.e_after(ffa.effect)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<E> LocalFunctor for EffectInstance<E> {
|
impl<'a, E: 'a> LocalFunctor<'a> for EffectInstance<E> {
|
||||||
fn stuff<'a, A: 'a, T: Pure<'a>>(fa: Self::F<'a, T::F<'a, A>>) -> T::F<'a, Self::F<'a, A>>
|
fn stuff<A: 'a, T: Pure<'a>>(fa: Self::Fa<T::Fa<A>>) -> T::Fa<Self::Fa<A>> {
|
||||||
where
|
|
||||||
Self: 'a,
|
|
||||||
{
|
|
||||||
T::fmap(
|
T::fmap(
|
||||||
|a| WithEffect {
|
|a| WithEffect {
|
||||||
value: a,
|
value: a,
|
||||||
|
@ -12,7 +12,6 @@ use futures::{
|
|||||||
|
|
||||||
use crate::func::*;
|
use crate::func::*;
|
||||||
|
|
||||||
#[derive(CovariantFunctor)]
|
|
||||||
pub struct FutureInstance;
|
pub struct FutureInstance;
|
||||||
|
|
||||||
impl WeakFunctor for FutureInstance {
|
impl WeakFunctor for FutureInstance {
|
||||||
@ -20,11 +19,11 @@ impl WeakFunctor for FutureInstance {
|
|||||||
}
|
}
|
||||||
|
|
||||||
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::F<'a, A>) -> Self::F<'a, B> {
|
fn fmap<A: 'a, B: 'a>(f: impl 'a + FnOnce(A) -> B, fa: Self::Fa<A>) -> Self::Fa<B> {
|
||||||
Box::pin(async { f(fa.await) })
|
Box::pin(async { f(fa.await) })
|
||||||
}
|
}
|
||||||
|
|
||||||
fn replace<A: 'a, B: 'a>(fa: Self::F<'a, A>, b: B) -> Self::F<'a, B> {
|
fn replace<A: 'a, B: 'a>(fa: Self::Fa<A>, b: B) -> Self::Fa<B> {
|
||||||
Box::pin(async {
|
Box::pin(async {
|
||||||
fa.await;
|
fa.await;
|
||||||
b
|
b
|
||||||
@ -33,16 +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::F<'a, A> {
|
fn pure<A: 'a>(a: A) -> Self::Fa<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>(
|
fn seq<A: 'a, B: 'a>(ff: Self::Fa<impl 'a + FnOnce(A) -> B>, fa: Self::Fa<A>) -> Self::Fa<B> {
|
||||||
ff: Self::F<'a, impl 'a + FnOnce(A) -> B>,
|
|
||||||
fa: Self::F<'a, A>,
|
|
||||||
) -> Self::F<'a, B> {
|
|
||||||
Box::pin(async {
|
Box::pin(async {
|
||||||
let (f, a) = join!(ff, fa);
|
let (f, a) = join!(ff, fa);
|
||||||
f(a)
|
f(a)
|
||||||
@ -53,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::F<'a, A>,
|
fa: Self::Fa<A>,
|
||||||
fb: Self::F<'a, B>,
|
fb: Self::Fa<B>,
|
||||||
) -> Self::F<'a, C> {
|
) -> Self::Fa<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)
|
||||||
@ -64,16 +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::F<'a, A>, Self::F<'a, B>)) -> Self::F<'a, (A, B)> {
|
fn tuple<A: 'a, B: 'a>((fa, fb): (Self::Fa<A>, Self::Fa<B>)) -> Self::Fa<(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>(
|
fn select<A: 'a, B: 'a>(fa: Self::Fa<A>, fb: Self::Fa<B>) -> SelectedWrapped<'a, A, B, Self> {
|
||||||
fa: Self::F<'a, A>,
|
|
||||||
fb: Self::F<'a, 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),
|
||||||
@ -84,24 +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::F<'a, A>, fb: Self::F<'a, B>) -> Self::F<'a, B> {
|
fn discard_first<A: 'a, B: 'a>(fa: Self::Fa<A>, fb: Self::Fa<B>) -> Self::Fa<B> {
|
||||||
Box::pin(async { join!(fa, fb).1 })
|
Box::pin(async { join!(fa, fb).1 })
|
||||||
}
|
}
|
||||||
|
|
||||||
fn discard_second<A: 'a, B: 'a>(fa: Self::F<'a, A>, fb: Self::F<'a, B>) -> Self::F<'a, A> {
|
fn discard_second<A: 'a, B: 'a>(fa: Self::Fa<A>, fb: Self::Fa<B>) -> Self::Fa<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>(
|
fn bind<A: 'a, B: 'a>(fa: Self::Fa<A>, f: impl 'a + FnOnce(A) -> Self::Fa<B>) -> Self::Fa<B> {
|
||||||
fa: Self::F<'a, A>,
|
|
||||||
f: impl 'a + FnOnce(A) -> Self::F<'a, B>,
|
|
||||||
) -> Self::F<'a, 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::F<'a, B> {
|
fn iterate<B: 'a>(mut f: impl Iterative<'a, T = Self, B = B>) -> Self::Fa<B> {
|
||||||
Box::pin(async move {
|
Box::pin(async move {
|
||||||
loop {
|
loop {
|
||||||
match f.next().await {
|
match f.next().await {
|
||||||
@ -112,27 +102,19 @@ impl<'a> Monad<'a> for FutureInstance {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
fn join<A: 'a>(ffa: Self::F<'a, Self::F<'a, A>>) -> Self::F<'a, A> {
|
fn join<A: 'a>(ffa: Self::Fa<Self::Fa<A>>) -> Self::Fa<A> {
|
||||||
Box::pin(async { ffa.await.await })
|
Box::pin(async { ffa.await.await })
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl SharedFunctor for FutureInstance {
|
impl<'a> SharedFunctorA<'a> for FutureInstance {
|
||||||
type Shared<'a, A: 'a + Clone> = Shared<Pin<Box<dyn 'a + Future<Output = A>>>>
|
type SharedA<A: 'a + Clone> = Shared<Pin<Box<dyn 'a + Future<Output = A>>>>;
|
||||||
where
|
|
||||||
Self: 'a;
|
|
||||||
|
|
||||||
fn share<'a, A: 'a + Clone>(fa: Self::F<'a, A>) -> Self::Shared<'a, A>
|
fn share<A: 'a + Clone>(fa: Self::Fa<A>) -> Self::SharedA<A> {
|
||||||
where
|
|
||||||
Self: 'a,
|
|
||||||
{
|
|
||||||
fa.shared()
|
fa.shared()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn unshare<'a, A: 'a + Clone>(sa: Self::Shared<'a, A>) -> Self::F<'a, A>
|
fn unshare<A: 'a + Clone>(sa: Self::SharedA<A>) -> Self::Fa<A> {
|
||||||
where
|
|
||||||
Self: 'a,
|
|
||||||
{
|
|
||||||
Box::pin(sa)
|
Box::pin(sa)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -11,7 +11,6 @@ use std::{cell::RefCell, rc::Rc};
|
|||||||
|
|
||||||
use crate::func::*;
|
use crate::func::*;
|
||||||
|
|
||||||
#[derive(CovariantFunctor)]
|
|
||||||
pub struct LazyInstance;
|
pub struct LazyInstance;
|
||||||
|
|
||||||
impl WeakFunctor for LazyInstance {
|
impl WeakFunctor for LazyInstance {
|
||||||
@ -19,32 +18,29 @@ impl WeakFunctor for LazyInstance {
|
|||||||
}
|
}
|
||||||
|
|
||||||
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::F<'a, A>) -> Self::F<'a, B> {
|
fn fmap<A: 'a, B: 'a>(f: impl 'a + FnOnce(A) -> B, fa: Self::Fa<A>) -> Self::Fa<B> {
|
||||||
Box::new(|| f(fa()))
|
Box::new(|| f(fa()))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn replace<A: 'a, B: 'a>(fa: Self::F<'a, A>, b: B) -> Self::F<'a, B> {
|
fn replace<A: 'a, B: 'a>(fa: Self::Fa<A>, b: B) -> Self::Fa<B> {
|
||||||
drop(fa);
|
drop(fa);
|
||||||
Box::new(|| b)
|
Box::new(|| b)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn void<A: 'a>(fa: Self::F<'a, A>) -> Self::F<'a, ()> {
|
fn void<A: 'a>(fa: Self::Fa<A>) -> Self::Fa<()> {
|
||||||
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::F<'a, A> {
|
fn pure<A: 'a>(a: A) -> Self::Fa<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>(
|
fn seq<A: 'a, B: 'a>(ff: Self::Fa<impl 'a + FnOnce(A) -> B>, fa: Self::Fa<A>) -> Self::Fa<B> {
|
||||||
ff: Self::F<'a, impl 'a + FnOnce(A) -> B>,
|
|
||||||
fa: Self::F<'a, A>,
|
|
||||||
) -> Self::F<'a, B> {
|
|
||||||
Box::new(|| ff()(fa()))
|
Box::new(|| ff()(fa()))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -52,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::F<'a, A>,
|
fa: Self::Fa<A>,
|
||||||
fb: Self::F<'a, B>,
|
fb: Self::Fa<B>,
|
||||||
) -> Self::F<'a, C> {
|
) -> Self::Fa<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::F<'a, A>, Self::F<'a, B>)) -> Self::F<'a, (A, B)> {
|
fn tuple<A: 'a, B: 'a>((fa, fb): (Self::Fa<A>, Self::Fa<B>)) -> Self::Fa<(A, B)> {
|
||||||
Box::new(|| (fa(), fb()))
|
Box::new(|| (fa(), fb()))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -68,26 +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::F<'a, A>, fb: Self::F<'a, B>) -> Self::F<'a, B> {
|
fn discard_first<A: 'a, B: 'a>(fa: Self::Fa<A>, fb: Self::Fa<B>) -> Self::Fa<B> {
|
||||||
drop(fa);
|
drop(fa);
|
||||||
fb
|
fb
|
||||||
}
|
}
|
||||||
|
|
||||||
fn discard_second<A: 'a, B: 'a>(fa: Self::F<'a, A>, fb: Self::F<'a, B>) -> Self::F<'a, A> {
|
fn discard_second<A: 'a, B: 'a>(fa: Self::Fa<A>, fb: Self::Fa<B>) -> Self::Fa<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>(
|
fn bind<A: 'a, B: 'a>(fa: Self::Fa<A>, f: impl 'a + FnOnce(A) -> Self::Fa<B>) -> Self::Fa<B> {
|
||||||
fa: Self::F<'a, A>,
|
|
||||||
f: impl 'a + FnOnce(A) -> Self::F<'a, B>,
|
|
||||||
) -> Self::F<'a, B> {
|
|
||||||
Box::new(|| f(fa())())
|
Box::new(|| f(fa())())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn iterate<B: 'a>(mut f: impl Iterative<'a, T = Self, B = B>) -> Self::F<'a, B> {
|
fn iterate<B: 'a>(mut f: impl Iterative<'a, T = Self, B = B>) -> Self::Fa<B> {
|
||||||
loop {
|
loop {
|
||||||
match f.next()() {
|
match f.next()() {
|
||||||
ControlFlow::Continue(next_f) => f = next_f,
|
ControlFlow::Continue(next_f) => f = next_f,
|
||||||
@ -96,7 +89,7 @@ impl<'a> Monad<'a> for LazyInstance {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn join<A: 'a>(ffa: Self::F<'a, Self::F<'a, A>>) -> Self::F<'a, A> {
|
fn join<A: 'a>(ffa: Self::Fa<Self::Fa<A>>) -> Self::Fa<A> {
|
||||||
Box::new(|| ffa()())
|
Box::new(|| ffa()())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -110,22 +103,14 @@ fn unshare<'a, A: 'a + Clone>(shared: &mut Option<Box<dyn 'a + FnOnce() -> A>>)
|
|||||||
a
|
a
|
||||||
}
|
}
|
||||||
|
|
||||||
impl SharedFunctor for LazyInstance {
|
impl<'a> SharedFunctorA<'a> for LazyInstance {
|
||||||
type Shared<'a, A: 'a + Clone> = Rc<RefCell<Option<Box<dyn 'a + FnOnce() -> A>>>>
|
type SharedA<A: 'a + Clone> = Rc<RefCell<Option<Box<dyn 'a + FnOnce() -> A>>>>;
|
||||||
where
|
|
||||||
Self: 'a;
|
|
||||||
|
|
||||||
fn share<'a, A: 'a + Clone>(fa: Self::F<'a, A>) -> Self::Shared<'a, A>
|
fn share<A: 'a + Clone>(fa: Self::Fa<A>) -> Self::SharedA<A> {
|
||||||
where
|
|
||||||
Self: 'a,
|
|
||||||
{
|
|
||||||
Rc::new(RefCell::new(Some(fa)))
|
Rc::new(RefCell::new(Some(fa)))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn unshare<'a, A: 'a + Clone>(sa: Self::Shared<'a, A>) -> Self::F<'a, A>
|
fn unshare<A: 'a + Clone>(sa: Self::SharedA<A>) -> Self::Fa<A> {
|
||||||
where
|
|
||||||
Self: 'a,
|
|
||||||
{
|
|
||||||
Box::new(move || unshare(&mut *sa.borrow_mut()))
|
Box::new(move || unshare(&mut *sa.borrow_mut()))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -9,7 +9,7 @@
|
|||||||
|
|
||||||
use crate::func::*;
|
use crate::func::*;
|
||||||
|
|
||||||
#[derive(SharedFunctor, CovariantFunctor)]
|
#[derive(SharedFunctor)]
|
||||||
pub struct OptionInstance;
|
pub struct OptionInstance;
|
||||||
|
|
||||||
impl WeakFunctor for OptionInstance {
|
impl WeakFunctor for OptionInstance {
|
||||||
@ -17,32 +17,29 @@ impl WeakFunctor for OptionInstance {
|
|||||||
}
|
}
|
||||||
|
|
||||||
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::F<'a, A>) -> Self::F<'a, B> {
|
fn fmap<A: 'a, B: 'a>(f: impl 'a + FnOnce(A) -> B, fa: Self::Fa<A>) -> Self::Fa<B> {
|
||||||
fa.map(f)
|
fa.map(f)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn replace<A: 'a, B: 'a>(fa: Self::F<'a, A>, b: B) -> Self::F<'a, B> {
|
fn replace<A: 'a, B: 'a>(fa: Self::Fa<A>, b: B) -> Self::Fa<B> {
|
||||||
fa?;
|
fa?;
|
||||||
Self::pure(b)
|
Self::pure(b)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn void<A: 'a>(fa: Self::F<'a, A>) -> Self::F<'a, ()> {
|
fn void<A: 'a>(fa: Self::Fa<A>) -> Self::Fa<()> {
|
||||||
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::F<'a, A> {
|
fn pure<A: 'a>(a: A) -> Self::Fa<A> {
|
||||||
Some(a)
|
Some(a)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> ApplicativeSeq<'a> for OptionInstance {
|
impl<'a> ApplicativeSeq<'a> for OptionInstance {
|
||||||
fn seq<A: 'a, B: 'a>(
|
fn seq<A: 'a, B: 'a>(ff: Self::Fa<impl 'a + FnOnce(A) -> B>, fa: Self::Fa<A>) -> Self::Fa<B> {
|
||||||
ff: Self::F<'a, impl 'a + FnOnce(A) -> B>,
|
|
||||||
fa: Self::F<'a, A>,
|
|
||||||
) -> Self::F<'a, B> {
|
|
||||||
Self::pure(ff?(fa?))
|
Self::pure(ff?(fa?))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -50,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::F<'a, A>,
|
fa: Self::Fa<A>,
|
||||||
fb: Self::F<'a, B>,
|
fb: Self::Fa<B>,
|
||||||
) -> Self::F<'a, C> {
|
) -> Self::Fa<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::F<'a, A>, Self::F<'a, B>)) -> Self::F<'a, (A, B)> {
|
fn tuple<A: 'a, B: 'a>((fa, fb): (Self::Fa<A>, Self::Fa<B>)) -> Self::Fa<(A, B)> {
|
||||||
Self::pure((fa?, fb?))
|
Self::pure((fa?, fb?))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -66,26 +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::F<'a, A>, fb: Self::F<'a, B>) -> Self::F<'a, B> {
|
fn discard_first<A: 'a, B: 'a>(fa: Self::Fa<A>, fb: Self::Fa<B>) -> Self::Fa<B> {
|
||||||
fa?;
|
fa?;
|
||||||
fb
|
fb
|
||||||
}
|
}
|
||||||
|
|
||||||
fn discard_second<A: 'a, B: 'a>(fa: Self::F<'a, A>, fb: Self::F<'a, B>) -> Self::F<'a, A> {
|
fn discard_second<A: 'a, B: 'a>(fa: Self::Fa<A>, fb: Self::Fa<B>) -> Self::Fa<A> {
|
||||||
fb?;
|
fb?;
|
||||||
fa
|
fa
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> Monad<'a> for OptionInstance {
|
impl<'a> Monad<'a> for OptionInstance {
|
||||||
fn bind<A: 'a, B: 'a>(
|
fn bind<A: 'a, B: 'a>(fa: Self::Fa<A>, f: impl 'a + FnOnce(A) -> Self::Fa<B>) -> Self::Fa<B> {
|
||||||
fa: Self::F<'a, A>,
|
|
||||||
f: impl 'a + FnOnce(A) -> Self::F<'a, B>,
|
|
||||||
) -> Self::F<'a, B> {
|
|
||||||
f(fa?)
|
f(fa?)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn iterate<B: 'a>(mut f: impl Iterative<'a, T = Self, B = B>) -> Self::F<'a, B> {
|
fn iterate<B: 'a>(mut f: impl Iterative<'a, T = Self, B = B>) -> Self::Fa<B> {
|
||||||
loop {
|
loop {
|
||||||
match f.next()? {
|
match f.next()? {
|
||||||
ControlFlow::Continue(next_f) => f = next_f,
|
ControlFlow::Continue(next_f) => f = next_f,
|
||||||
@ -94,18 +88,13 @@ impl<'a> Monad<'a> for OptionInstance {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn join<A: 'a>(ffa: Self::F<'a, Self::F<'a, A>>) -> Self::F<'a, A> {
|
fn join<A: 'a>(ffa: Self::Fa<Self::Fa<A>>) -> Self::Fa<A> {
|
||||||
ffa?
|
ffa?
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl LocalFunctor for OptionInstance {
|
impl<'a> LocalFunctor<'a> for OptionInstance {
|
||||||
fn unstuff<'a, A: 'a, B: 'a>(
|
fn unstuff<A: 'a, B: 'a>(state: Self::Fa<ControlFlow<B, A>>) -> ControlFlow<Self::Fa<B>, A> {
|
||||||
state: Self::F<'a, ControlFlow<B, A>>,
|
|
||||||
) -> ControlFlow<Self::F<'a, B>, A>
|
|
||||||
where
|
|
||||||
Self: '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)),
|
||||||
@ -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>>
|
fn stuff<A: 'a, T: Pure<'a>>(fa: Self::Fa<T::Fa<A>>) -> T::Fa<Self::Fa<A>> {
|
||||||
where
|
|
||||||
Self: '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),
|
||||||
@ -125,7 +111,7 @@ impl LocalFunctor for OptionInstance {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> Fail<'a, ()> for OptionInstance {
|
impl<'a> Fail<'a, ()> for OptionInstance {
|
||||||
fn fail<A: 'a>(_e: ()) -> Self::F<'a, A> {
|
fn fail<A: 'a>(_e: ()) -> Self::Fa<A> {
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -136,21 +122,18 @@ mod option_tests {
|
|||||||
|
|
||||||
use super::OptionInstance as T;
|
use super::OptionInstance as T;
|
||||||
|
|
||||||
impl tests::Eqr for T {
|
impl<'a> tests::Eqr<'a> for T {
|
||||||
fn eqr<'a, A: PartialEq + std::fmt::Debug + 'a>(
|
fn eqr<A: PartialEq + std::fmt::Debug + 'a>(
|
||||||
name: &'a str,
|
name: &'a str,
|
||||||
left: Self::F<'a, A>,
|
left: Self::Fa<A>,
|
||||||
right: Self::F<'a, A>,
|
right: Self::Fa<A>,
|
||||||
) -> tests::R {
|
) -> tests::R {
|
||||||
tests::eqr(name, left, right)
|
tests::eqr(name, left, right)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl test_suite::FunctorTestSuite for T {
|
impl<'a> test_suite::FunctorTestSuite<'a> for T {
|
||||||
fn sample<'a, A: 'a, F: FnMut(&'a dyn Fn(A) -> Self::F<'a, A>)>(mut f: F)
|
fn sample<A: 'a, F: FnMut(&'a dyn Fn(A) -> Self::Fa<A>)>(mut f: F) {
|
||||||
where
|
|
||||||
Self::F<'a, A>: 'a,
|
|
||||||
{
|
|
||||||
f(&|_| None);
|
f(&|_| None);
|
||||||
f(&|a| Some(a));
|
f(&|a| Some(a));
|
||||||
}
|
}
|
||||||
|
@ -12,28 +12,28 @@ pub trait DeriveApplicative {}
|
|||||||
impl<O: DeriveMonad> DeriveApplicative for O {}
|
impl<O: DeriveMonad> DeriveApplicative for O {}
|
||||||
pub trait DeriveMonad {}
|
pub trait DeriveMonad {}
|
||||||
|
|
||||||
impl<T: WeakFunctor, O: DeriveWeakFunctor> WeakFunctor for OverloadInstance<T, O> {
|
impl<'a, T: WeakFunctorA<'a>, O: 'a + DeriveWeakFunctor> WeakFunctorA<'a>
|
||||||
type F<'a, A: 'a> = T::F<'a, A>
|
for OverloadInstance<T, O>
|
||||||
where
|
{
|
||||||
Self: '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::F<'a, A>) -> Self::F<'a, B> {
|
fn fmap<A: 'a, B: 'a>(f: impl 'a + FnOnce(A) -> B, fa: Self::Fa<A>) -> Self::Fa<B> {
|
||||||
T::fmap(f, fa)
|
T::fmap(f, fa)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn replace<A: 'a, B: 'a>(fa: Self::F<'a, A>, b: B) -> Self::F<'a, B> {
|
fn replace<A: 'a, B: 'a>(fa: Self::Fa<A>, b: B) -> Self::Fa<B> {
|
||||||
T::replace(fa, b)
|
T::replace(fa, b)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn void<A: 'a>(fa: Self::F<'a, A>) -> Self::F<'a, ()> {
|
fn void<A: 'a>(fa: Self::Fa<A>) -> Self::Fa<()> {
|
||||||
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::F<'a, A> {
|
fn pure<A: 'a>(a: A) -> Self::Fa<A> {
|
||||||
T::pure(a)
|
T::pure(a)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -41,10 +41,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>(
|
fn seq<A: 'a, B: 'a>(ff: Self::Fa<impl 'a + FnOnce(A) -> B>, fa: Self::Fa<A>) -> Self::Fa<B> {
|
||||||
ff: Self::F<'a, impl 'a + FnOnce(A) -> B>,
|
|
||||||
fa: Self::F<'a, A>,
|
|
||||||
) -> Self::F<'a, B> {
|
|
||||||
T::seq(ff, fa)
|
T::seq(ff, fa)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -54,9 +51,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::F<'a, A>,
|
fa: Self::Fa<A>,
|
||||||
fb: Self::F<'a, B>,
|
fb: Self::Fa<B>,
|
||||||
) -> Self::F<'a, C> {
|
) -> Self::Fa<C> {
|
||||||
T::la2(f, fa, fb)
|
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>
|
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::F<'a, A>, Self::F<'a, B>)) -> Self::F<'a, (A, B)> {
|
fn tuple<A: 'a, B: 'a>(fab: (Self::Fa<A>, Self::Fa<B>)) -> Self::Fa<(A, B)> {
|
||||||
T::tuple(fab)
|
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>
|
impl<'a, T: ApplicativeSelect<'a>, O: 'a + DeriveApplicative> ApplicativeSelect<'a>
|
||||||
for OverloadInstance<T, O>
|
for OverloadInstance<T, O>
|
||||||
{
|
{
|
||||||
fn select<A: 'a, B: 'a>(
|
fn select<A: 'a, B: 'a>(fa: Self::Fa<A>, fb: Self::Fa<B>) -> SelectedWrapped<'a, A, B, Self> {
|
||||||
fa: Self::F<'a, A>,
|
|
||||||
fb: Self::F<'a, 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),
|
||||||
@ -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<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::F<'a, A>, fb: Self::F<'a, B>) -> Self::F<'a, B> {
|
fn discard_first<A: 'a, B: 'a>(fa: Self::Fa<A>, fb: Self::Fa<B>) -> Self::Fa<B> {
|
||||||
T::discard_first(fa, fb)
|
T::discard_first(fa, fb)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn discard_second<A: 'a, B: 'a>(fa: Self::F<'a, A>, fb: Self::F<'a, B>) -> Self::F<'a, A> {
|
fn discard_second<A: 'a, B: 'a>(fa: Self::Fa<A>, fb: Self::Fa<B>) -> Self::Fa<A> {
|
||||||
T::discard_second(fa, fb)
|
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<T, O> {
|
impl<'a, T: Monad<'a>, O: 'a + DeriveMonad> Monad<'a> for OverloadInstance<T, O> {
|
||||||
fn bind<A: 'a, B: 'a>(
|
fn bind<A: 'a, B: 'a>(fa: Self::Fa<A>, f: impl 'a + FnOnce(A) -> Self::Fa<B>) -> Self::Fa<B> {
|
||||||
fa: Self::F<'a, A>,
|
|
||||||
f: impl 'a + FnOnce(A) -> Self::F<'a, B>,
|
|
||||||
) -> Self::F<'a, B> {
|
|
||||||
T::bind(fa, f)
|
T::bind(fa, f)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn iterate<B: 'a>(f: impl Iterative<'a, T = Self, B = B>) -> Self::F<'a, B> {
|
fn iterate<B: 'a>(f: impl Iterative<'a, T = Self, B = B>) -> Self::Fa<B> {
|
||||||
T::iterate(OverloadIterative::new(f))
|
T::iterate(OverloadIterative::new(f))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn join<A: 'a>(ffa: Self::F<'a, Self::F<'a, A>>) -> Self::F<'a, A> {
|
fn join<A: 'a>(ffa: Self::Fa<Self::Fa<A>>) -> Self::Fa<A> {
|
||||||
T::join(ffa)
|
T::join(ffa)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -147,7 +138,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::F<'a, A> {
|
fn fail<A: 'a>(e: E) -> Self::Fa<A> {
|
||||||
T::fail(Ok(e))
|
T::fail(Ok(e))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -203,33 +194,18 @@ impl<'a, Ex: 'a, Fallible: MonadFailAny<'a>> MonadFailAny<'a> for DeriveFailAny<
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T: SharedFunctor, O: DeriveWeakFunctor> SharedFunctor for OverloadInstance<T, O> {
|
impl<'a, T: SharedFunctorA<'a>, O: 'a + DeriveWeakFunctor> SharedFunctorA<'a>
|
||||||
type Shared<'a, A: 'a + Clone> = T::Shared<'a, A>
|
for OverloadInstance<T, O>
|
||||||
where
|
{
|
||||||
Self: 'a;
|
type SharedA<A: 'a + Clone> = T::SharedA<A>;
|
||||||
|
|
||||||
fn share<'a, A: 'a + Clone>(fa: Self::F<'a, A>) -> Self::Shared<'a, A>
|
fn share<A: 'a + Clone>(fa: Self::Fa<A>) -> Self::SharedA<A> {
|
||||||
where
|
|
||||||
Self: 'a,
|
|
||||||
{
|
|
||||||
T::share(fa)
|
T::share(fa)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn unshare<'a, A: 'a + Clone>(sa: Self::Shared<'a, A>) -> Self::F<'a, A>
|
fn unshare<A: 'a + Clone>(sa: Self::SharedA<A>) -> Self::Fa<A> {
|
||||||
where
|
|
||||||
Self: 'a,
|
|
||||||
{
|
|
||||||
T::unshare(sa)
|
T::unshare(sa)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T: CovariantFunctor, O: DeriveWeakFunctor> CovariantFunctor for OverloadInstance<T, O> {
|
|
||||||
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<T, Ex> = OverloadInstance<T, DeriveFail<Ex>>;
|
pub type EmbedFail<T, Ex> = OverloadInstance<T, DeriveFail<Ex>>;
|
||||||
|
@ -9,7 +9,7 @@
|
|||||||
|
|
||||||
use crate::func::*;
|
use crate::func::*;
|
||||||
|
|
||||||
#[derive(SharedFunctor, CovariantFunctor)]
|
#[derive(SharedFunctor)]
|
||||||
pub struct ResultInstance<E>(E);
|
pub struct ResultInstance<E>(E);
|
||||||
|
|
||||||
impl<E> WeakFunctor for ResultInstance<E> {
|
impl<E> WeakFunctor for ResultInstance<E> {
|
||||||
@ -17,32 +17,29 @@ impl<E> WeakFunctor for ResultInstance<E> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
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::F<'a, A>) -> Self::F<'a, B> {
|
fn fmap<A: 'a, B: 'a>(f: impl 'a + FnOnce(A) -> B, fa: Self::Fa<A>) -> Self::Fa<B> {
|
||||||
fa.map(f)
|
fa.map(f)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn replace<A: 'a, B: 'a>(fa: Self::F<'a, A>, b: B) -> Self::F<'a, B> {
|
fn replace<A: 'a, B: 'a>(fa: Self::Fa<A>, b: B) -> Self::Fa<B> {
|
||||||
fa?;
|
fa?;
|
||||||
Self::pure(b)
|
Self::pure(b)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn void<A: 'a>(fa: Self::F<'a, A>) -> Self::F<'a, ()> {
|
fn void<A: 'a>(fa: Self::Fa<A>) -> Self::Fa<()> {
|
||||||
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::F<'a, A> {
|
fn pure<A: 'a>(a: A) -> Self::Fa<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>(
|
fn seq<A: 'a, B: 'a>(ff: Self::Fa<impl 'a + FnOnce(A) -> B>, fa: Self::Fa<A>) -> Self::Fa<B> {
|
||||||
ff: Self::F<'a, impl 'a + FnOnce(A) -> B>,
|
|
||||||
fa: Self::F<'a, A>,
|
|
||||||
) -> Self::F<'a, B> {
|
|
||||||
Self::pure(ff?(fa?))
|
Self::pure(ff?(fa?))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -50,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::F<'a, A>,
|
fa: Self::Fa<A>,
|
||||||
fb: Self::F<'a, B>,
|
fb: Self::Fa<B>,
|
||||||
) -> Self::F<'a, C> {
|
) -> Self::Fa<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::F<'a, A>, Self::F<'a, B>)) -> Self::F<'a, (A, B)> {
|
fn tuple<A: 'a, B: 'a>((fa, fb): (Self::Fa<A>, Self::Fa<B>)) -> Self::Fa<(A, B)> {
|
||||||
Self::pure((fa?, fb?))
|
Self::pure((fa?, fb?))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -66,26 +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::F<'a, A>, fb: Self::F<'a, B>) -> Self::F<'a, B> {
|
fn discard_first<A: 'a, B: 'a>(fa: Self::Fa<A>, fb: Self::Fa<B>) -> Self::Fa<B> {
|
||||||
fa?;
|
fa?;
|
||||||
fb
|
fb
|
||||||
}
|
}
|
||||||
|
|
||||||
fn discard_second<A: 'a, B: 'a>(fa: Self::F<'a, A>, fb: Self::F<'a, B>) -> Self::F<'a, A> {
|
fn discard_second<A: 'a, B: 'a>(fa: Self::Fa<A>, fb: Self::Fa<B>) -> Self::Fa<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>(
|
fn bind<A: 'a, B: 'a>(fa: Self::Fa<A>, f: impl 'a + FnOnce(A) -> Self::Fa<B>) -> Self::Fa<B> {
|
||||||
fa: Self::F<'a, A>,
|
|
||||||
f: impl 'a + FnOnce(A) -> Self::F<'a, B>,
|
|
||||||
) -> Self::F<'a, B> {
|
|
||||||
f(fa?)
|
f(fa?)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn iterate<B: 'a>(mut f: impl Iterative<'a, T = Self, B = B>) -> Self::F<'a, B> {
|
fn iterate<B: 'a>(mut f: impl Iterative<'a, T = Self, B = B>) -> Self::Fa<B> {
|
||||||
loop {
|
loop {
|
||||||
match f.next()? {
|
match f.next()? {
|
||||||
ControlFlow::Continue(next_f) => f = next_f,
|
ControlFlow::Continue(next_f) => f = next_f,
|
||||||
@ -94,18 +88,13 @@ impl<'a, E: 'a> Monad<'a> for ResultInstance<E> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn join<A: 'a>(ffa: Self::F<'a, Self::F<'a, A>>) -> Self::F<'a, A> {
|
fn join<A: 'a>(ffa: Self::Fa<Self::Fa<A>>) -> Self::Fa<A> {
|
||||||
ffa?
|
ffa?
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<E> LocalFunctor for ResultInstance<E> {
|
impl<'a, E: 'a> LocalFunctor<'a> for ResultInstance<E> {
|
||||||
fn unstuff<'a, A: 'a, B: 'a>(
|
fn unstuff<A: 'a, B: 'a>(state: Self::Fa<ControlFlow<B, A>>) -> ControlFlow<Self::Fa<B>, A> {
|
||||||
state: Self::F<'a, ControlFlow<B, A>>,
|
|
||||||
) -> ControlFlow<Self::F<'a, B>, A>
|
|
||||||
where
|
|
||||||
Self: '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)),
|
||||||
@ -113,10 +102,7 @@ impl<E> LocalFunctor for ResultInstance<E> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn stuff<'a, A: 'a, T: Pure<'a>>(fa: Self::F<'a, T::F<'a, A>>) -> T::F<'a, Self::F<'a, A>>
|
fn stuff<A: 'a, T: Pure<'a>>(fa: Self::Fa<T::Fa<A>>) -> T::Fa<Self::Fa<A>> {
|
||||||
where
|
|
||||||
Self: '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)),
|
||||||
@ -125,7 +111,7 @@ impl<E> LocalFunctor 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::F<'a, A> {
|
fn fail<A: 'a>(e: E) -> Self::Fa<A> {
|
||||||
Err(e)
|
Err(e)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -4,7 +4,7 @@
|
|||||||
|
|
||||||
use crate::func::*;
|
use crate::func::*;
|
||||||
|
|
||||||
#[derive(SharedFunctor, CovariantFunctor)]
|
#[derive(SharedFunctor)]
|
||||||
pub struct SoloInstance;
|
pub struct SoloInstance;
|
||||||
|
|
||||||
impl WeakFunctor for SoloInstance {
|
impl WeakFunctor for SoloInstance {
|
||||||
@ -12,31 +12,28 @@ impl WeakFunctor for SoloInstance {
|
|||||||
}
|
}
|
||||||
|
|
||||||
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::F<'a, A>) -> Self::F<'a, B> {
|
fn fmap<A: 'a, B: 'a>(f: impl 'a + FnOnce(A) -> B, fa: Self::Fa<A>) -> Self::Fa<B> {
|
||||||
f(fa)
|
f(fa)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn replace<A: 'a, B: 'a>(fa: Self::F<'a, A>, b: B) -> Self::F<'a, B> {
|
fn replace<A: 'a, B: 'a>(fa: Self::Fa<A>, b: B) -> Self::Fa<B> {
|
||||||
drop(fa);
|
drop(fa);
|
||||||
b
|
b
|
||||||
}
|
}
|
||||||
|
|
||||||
fn void<A: 'a>(fa: Self::F<'a, A>) -> Self::F<'a, ()> {
|
fn void<A: 'a>(fa: Self::Fa<A>) -> Self::Fa<()> {
|
||||||
drop(fa);
|
drop(fa);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> Pure<'a> for SoloInstance {
|
impl<'a> Pure<'a> for SoloInstance {
|
||||||
fn pure<A: 'a>(a: A) -> Self::F<'a, A> {
|
fn pure<A: 'a>(a: A) -> Self::Fa<A> {
|
||||||
a
|
a
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> ApplicativeSeq<'a> for SoloInstance {
|
impl<'a> ApplicativeSeq<'a> for SoloInstance {
|
||||||
fn seq<A: 'a, B: 'a>(
|
fn seq<A: 'a, B: 'a>(ff: Self::Fa<impl 'a + FnOnce(A) -> B>, fa: Self::Fa<A>) -> Self::Fa<B> {
|
||||||
ff: Self::F<'a, impl 'a + FnOnce(A) -> B>,
|
|
||||||
fa: Self::F<'a, A>,
|
|
||||||
) -> Self::F<'a, B> {
|
|
||||||
ff(fa)
|
ff(fa)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -44,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::F<'a, A>,
|
fa: Self::Fa<A>,
|
||||||
fb: Self::F<'a, B>,
|
fb: Self::Fa<B>,
|
||||||
) -> Self::F<'a, C> {
|
) -> Self::Fa<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::F<'a, A>, Self::F<'a, B>)) -> Self::F<'a, (A, B)> {
|
fn tuple<A: 'a, B: 'a>((fa, fb): (Self::Fa<A>, Self::Fa<B>)) -> Self::Fa<(A, B)> {
|
||||||
(fa, fb)
|
(fa, fb)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -60,26 +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::F<'a, A>, fb: Self::F<'a, B>) -> Self::F<'a, B> {
|
fn discard_first<A: 'a, B: 'a>(fa: Self::Fa<A>, fb: Self::Fa<B>) -> Self::Fa<B> {
|
||||||
drop(fa);
|
drop(fa);
|
||||||
fb
|
fb
|
||||||
}
|
}
|
||||||
|
|
||||||
fn discard_second<A: 'a, B: 'a>(fa: Self::F<'a, A>, fb: Self::F<'a, B>) -> Self::F<'a, A> {
|
fn discard_second<A: 'a, B: 'a>(fa: Self::Fa<A>, fb: Self::Fa<B>) -> Self::Fa<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>(
|
fn bind<A: 'a, B: 'a>(fa: Self::Fa<A>, f: impl 'a + FnOnce(A) -> Self::Fa<B>) -> Self::Fa<B> {
|
||||||
fa: Self::F<'a, A>,
|
|
||||||
f: impl 'a + FnOnce(A) -> Self::F<'a, B>,
|
|
||||||
) -> Self::F<'a, B> {
|
|
||||||
f(fa)
|
f(fa)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn iterate<B: 'a>(mut f: impl Iterative<'a, T = Self, B = B>) -> Self::F<'a, B> {
|
fn iterate<B: 'a>(mut f: impl Iterative<'a, T = Self, B = B>) -> Self::Fa<B> {
|
||||||
loop {
|
loop {
|
||||||
match f.next() {
|
match f.next() {
|
||||||
ControlFlow::Continue(next_f) => f = next_f,
|
ControlFlow::Continue(next_f) => f = next_f,
|
||||||
@ -88,31 +82,23 @@ impl<'a> Monad<'a> for SoloInstance {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn join<A: 'a>(ffa: Self::F<'a, Self::F<'a, A>>) -> Self::F<'a, A> {
|
fn join<A: 'a>(ffa: Self::Fa<Self::Fa<A>>) -> Self::Fa<A> {
|
||||||
ffa
|
ffa
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl LocalFunctor for SoloInstance {
|
impl<'a> LocalFunctor<'a> for SoloInstance {
|
||||||
fn unstuff<'a, A: 'a, B: 'a>(
|
fn unstuff<A: 'a, B: 'a>(state: Self::Fa<ControlFlow<B, A>>) -> ControlFlow<Self::Fa<B>, A> {
|
||||||
state: Self::F<'a, ControlFlow<B, A>>,
|
|
||||||
) -> ControlFlow<Self::F<'a, B>, A>
|
|
||||||
where
|
|
||||||
Self: 'a,
|
|
||||||
{
|
|
||||||
state
|
state
|
||||||
}
|
}
|
||||||
|
|
||||||
fn stuff<'a, A: 'a, T: Pure<'a>>(fa: Self::F<'a, T::F<'a, A>>) -> T::F<'a, Self::F<'a, A>>
|
fn stuff<A: 'a, T: Pure<'a>>(fa: Self::Fa<T::Fa<A>>) -> T::Fa<Self::Fa<A>> {
|
||||||
where
|
|
||||||
Self: '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::F<'a, A> {
|
fn fail<A: 'a>(e: std::convert::Infallible) -> Self::Fa<A> {
|
||||||
match e {}
|
match e {}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -124,11 +124,11 @@ impl WeakFunctor for StacklessInstance {
|
|||||||
}
|
}
|
||||||
|
|
||||||
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::F<'a, A>) -> Self::F<'a, B> {
|
fn fmap<A: 'a, B: 'a>(f: impl 'a + FnOnce(A) -> B, fa: Self::Fa<A>) -> Self::Fa<B> {
|
||||||
fa.map(f)
|
fa.map(f)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn replace<A: 'a, B: 'a>(fa: Self::F<'a, A>, b: B) -> Self::F<'a, B> {
|
fn replace<A: 'a, B: 'a>(fa: Self::Fa<A>, b: B) -> Self::Fa<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,16 +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::F<'a, A> {
|
fn pure<A: 'a>(a: A) -> Self::Fa<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>(
|
fn seq<A: 'a, B: 'a>(ff: Self::Fa<impl 'a + FnOnce(A) -> B>, fa: Self::Fa<A>) -> Self::Fa<B> {
|
||||||
ff: Self::F<'a, impl 'a + FnOnce(A) -> B>,
|
|
||||||
fa: Self::F<'a, A>,
|
|
||||||
) -> Self::F<'a, B> {
|
|
||||||
ff.bind(|f| fa.map(f))
|
ff.bind(|f| fa.map(f))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -159,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::F<'a, A>,
|
fa: Self::Fa<A>,
|
||||||
fb: Self::F<'a, B>,
|
fb: Self::Fa<B>,
|
||||||
) -> Self::F<'a, C> {
|
) -> Self::Fa<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::F<'a, A>, Self::F<'a, B>)) -> Self::F<'a, (A, B)> {
|
fn tuple<A: 'a, B: 'a>((fa, fb): (Self::Fa<A>, Self::Fa<B>)) -> Self::Fa<(A, B)> {
|
||||||
Self::_tuple_via_la2((fa, fb))
|
Self::_tuple_via_la2((fa, fb))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -175,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::F<'a, A>, fb: Self::F<'a, B>) -> Self::F<'a, B> {
|
fn discard_first<A: 'a, B: 'a>(fa: Self::Fa<A>, fb: Self::Fa<B>) -> Self::Fa<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)))),
|
||||||
@ -184,7 +181,7 @@ impl<'a> Applicative<'a> for StacklessInstance {
|
|||||||
}))
|
}))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn discard_second<A: 'a, B: 'a>(fa: Self::F<'a, A>, fb: Self::F<'a, B>) -> Self::F<'a, A> {
|
fn discard_second<A: 'a, B: 'a>(fa: Self::Fa<A>, fb: Self::Fa<B>) -> Self::Fa<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)))),
|
||||||
@ -195,14 +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>(
|
fn bind<A: 'a, B: 'a>(fa: Self::Fa<A>, f: impl 'a + FnOnce(A) -> Self::Fa<B>) -> Self::Fa<B> {
|
||||||
fa: Self::F<'a, A>,
|
|
||||||
f: impl 'a + FnOnce(A) -> Self::F<'a, B>,
|
|
||||||
) -> Self::F<'a, B> {
|
|
||||||
fa.bind(f)
|
fa.bind(f)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn iterate<B: 'a>(f: impl Iterative<'a, T = Self, B = B>) -> Self::F<'a, B> {
|
fn iterate<B: 'a>(f: impl Iterative<'a, T = Self, B = B>) -> Self::Fa<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),
|
||||||
@ -211,7 +205,7 @@ impl<'a> Monad<'a> for StacklessInstance {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
fn join<A: 'a>(ffa: Self::F<'a, Self::F<'a, A>>) -> Self::F<'a, A> {
|
fn join<A: 'a>(ffa: Self::Fa<Self::Fa<A>>) -> Self::Fa<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();
|
||||||
@ -234,21 +228,18 @@ mod stackless_test {
|
|||||||
|
|
||||||
use super::StacklessInstance as T;
|
use super::StacklessInstance as T;
|
||||||
|
|
||||||
impl tests::Eqr for T {
|
impl<'a> tests::Eqr<'a> for T {
|
||||||
fn eqr<'a, A: PartialEq + std::fmt::Debug + 'a>(
|
fn eqr<A: PartialEq + std::fmt::Debug + 'a>(
|
||||||
name: &'a str,
|
name: &'a str,
|
||||||
left: Self::F<'a, A>,
|
left: Self::Fa<A>,
|
||||||
right: Self::F<'a, A>,
|
right: Self::Fa<A>,
|
||||||
) -> tests::R {
|
) -> tests::R {
|
||||||
tests::eqr(name, left.evaluate(), right.evaluate())
|
tests::eqr(name, left.evaluate(), right.evaluate())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl test_suite::FunctorTestSuite for T {
|
impl<'a> test_suite::FunctorTestSuite<'a> for T {
|
||||||
fn sample<'a, A: 'a, F: FnMut(&'a dyn Fn(A) -> Self::F<'a, A>)>(mut f: F)
|
fn sample<A: 'a, F: FnMut(&'a dyn Fn(A) -> Self::Fa<A>)>(mut f: F) {
|
||||||
where
|
|
||||||
Self::F<'a, A>: 'a,
|
|
||||||
{
|
|
||||||
f(&|a| a.into());
|
f(&|a| a.into());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -7,7 +7,6 @@ use futures::{
|
|||||||
|
|
||||||
use crate::func::*;
|
use crate::func::*;
|
||||||
|
|
||||||
#[derive(CovariantFunctor)]
|
|
||||||
pub struct TryFutureInstance<E>(E);
|
pub struct TryFutureInstance<E>(E);
|
||||||
|
|
||||||
impl<E> WeakFunctor for TryFutureInstance<E> {
|
impl<E> WeakFunctor for TryFutureInstance<E> {
|
||||||
@ -15,11 +14,11 @@ impl<E> WeakFunctor for TryFutureInstance<E> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
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::F<'a, A>) -> Self::F<'a, B> {
|
fn fmap<A: 'a, B: 'a>(f: impl 'a + FnOnce(A) -> B, fa: Self::Fa<A>) -> Self::Fa<B> {
|
||||||
Box::pin(async { Ok(f(fa.await?)) })
|
Box::pin(async { Ok(f(fa.await?)) })
|
||||||
}
|
}
|
||||||
|
|
||||||
fn replace<A: 'a, B: 'a>(fa: Self::F<'a, A>, b: B) -> Self::F<'a, B> {
|
fn replace<A: 'a, B: 'a>(fa: Self::Fa<A>, b: B) -> Self::Fa<B> {
|
||||||
Box::pin(async {
|
Box::pin(async {
|
||||||
fa.await?;
|
fa.await?;
|
||||||
Ok(b)
|
Ok(b)
|
||||||
@ -28,16 +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::F<'a, A> {
|
fn pure<A: 'a>(a: A) -> Self::Fa<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>(
|
fn seq<A: 'a, B: 'a>(ff: Self::Fa<impl 'a + FnOnce(A) -> B>, fa: Self::Fa<A>) -> Self::Fa<B> {
|
||||||
ff: Self::F<'a, impl 'a + FnOnce(A) -> B>,
|
|
||||||
fa: Self::F<'a, A>,
|
|
||||||
) -> Self::F<'a, 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))
|
||||||
@ -48,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::F<'a, A>,
|
fa: Self::Fa<A>,
|
||||||
fb: Self::F<'a, B>,
|
fb: Self::Fa<B>,
|
||||||
) -> Self::F<'a, C> {
|
) -> Self::Fa<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))
|
||||||
@ -59,16 +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::F<'a, A>, Self::F<'a, B>)) -> Self::F<'a, (A, B)> {
|
fn tuple<A: 'a, B: 'a>((fa, fb): (Self::Fa<A>, Self::Fa<B>)) -> Self::Fa<(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>(
|
fn select<A: 'a, B: 'a>(fa: Self::Fa<A>, fb: Self::Fa<B>) -> SelectedWrapped<'a, A, B, Self> {
|
||||||
fa: Self::F<'a, A>,
|
|
||||||
fb: Self::F<'a, 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)),
|
||||||
@ -81,24 +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::F<'a, A>, fb: Self::F<'a, B>) -> Self::F<'a, B> {
|
fn discard_first<A: 'a, B: 'a>(fa: Self::Fa<A>, fb: Self::Fa<B>) -> Self::Fa<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::F<'a, A>, fb: Self::F<'a, B>) -> Self::F<'a, A> {
|
fn discard_second<A: 'a, B: 'a>(fa: Self::Fa<A>, fb: Self::Fa<B>) -> Self::Fa<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>(
|
fn bind<A: 'a, B: 'a>(fa: Self::Fa<A>, f: impl 'a + FnOnce(A) -> Self::Fa<B>) -> Self::Fa<B> {
|
||||||
fa: Self::F<'a, A>,
|
|
||||||
f: impl 'a + FnOnce(A) -> Self::F<'a, B>,
|
|
||||||
) -> Self::F<'a, 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::F<'a, B> {
|
fn iterate<B: 'a>(mut f: impl Iterative<'a, T = Self, B = B>) -> Self::Fa<B> {
|
||||||
Box::pin(async move {
|
Box::pin(async move {
|
||||||
loop {
|
loop {
|
||||||
match f.next().await? {
|
match f.next().await? {
|
||||||
@ -109,33 +99,25 @@ impl<'a, E: 'a> Monad<'a> for TryFutureInstance<E> {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
fn join<A: 'a>(ffa: Self::F<'a, Self::F<'a, A>>) -> Self::F<'a, A> {
|
fn join<A: 'a>(ffa: Self::Fa<Self::Fa<A>>) -> Self::Fa<A> {
|
||||||
Box::pin(async { ffa.await?.await })
|
Box::pin(async { ffa.await?.await })
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<E: Clone> SharedFunctor for TryFutureInstance<E> {
|
impl<'a, E: 'a + Clone> SharedFunctorA<'a> for TryFutureInstance<E> {
|
||||||
type Shared<'a, A: 'a + Clone> = Shared<Pin<Box<dyn 'a + Future<Output = Result<A, E>>>>>
|
type SharedA<A: 'a + Clone> = Shared<Pin<Box<dyn 'a + Future<Output = Result<A, E>>>>>;
|
||||||
where
|
|
||||||
Self: 'a;
|
|
||||||
|
|
||||||
fn share<'a, A: 'a + Clone>(fa: Self::F<'a, A>) -> Self::Shared<'a, A>
|
fn share<A: 'a + Clone>(fa: Self::Fa<A>) -> Self::SharedA<A> {
|
||||||
where
|
|
||||||
Self: 'a,
|
|
||||||
{
|
|
||||||
fa.shared()
|
fa.shared()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn unshare<'a, A: 'a + Clone>(sa: Self::Shared<'a, A>) -> Self::F<'a, A>
|
fn unshare<A: 'a + Clone>(sa: Self::SharedA<A>) -> Self::Fa<A> {
|
||||||
where
|
|
||||||
Self: '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::F<'a, A> {
|
fn fail<A: 'a>(e: E) -> Self::Fa<A> {
|
||||||
Box::pin(async { Err(e) })
|
Box::pin(async { Err(e) })
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,14 +1,11 @@
|
|||||||
use super::tests::*;
|
use super::tests::*;
|
||||||
use super::*;
|
use super::*;
|
||||||
|
|
||||||
pub trait FunctorTestSuite: WeakFunctor + Eqr {
|
pub trait FunctorTestSuite<'a>: WeakFunctorA<'a> + Eqr<'a> {
|
||||||
fn sample<'a, A: 'a, F: FnMut(&'a dyn Fn(A) -> Self::F<'a, A>)>(f: F)
|
fn sample<A: 'a, F: FnMut(&'a dyn Fn(A) -> Self::Fa<A>)>(f: F);
|
||||||
where
|
|
||||||
Self::F<'a, A>: 'a,
|
|
||||||
Self: 'a;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
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();
|
let mut res = R::default();
|
||||||
T::sample(|pa| {
|
T::sample(|pa| {
|
||||||
res += fmap_respects_identity::<T, _>(|| pa(2));
|
res += fmap_respects_identity::<T, _>(|| pa(2));
|
||||||
@ -19,7 +16,7 @@ pub fn functor_follows_laws<'a, T: Functor<'a> + FunctorTestSuite>() -> R {
|
|||||||
res
|
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>();
|
let mut res = functor_follows_laws::<T>();
|
||||||
T::sample(|pa| {
|
T::sample(|pa| {
|
||||||
res += seq_respects_identity::<T, _>(|| pa(2));
|
res += seq_respects_identity::<T, _>(|| pa(2));
|
||||||
@ -55,7 +52,7 @@ pub fn applicative_follows_laws<'a, T: Applicative<'a> + FunctorTestSuite>() ->
|
|||||||
res
|
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>();
|
let mut res = applicative_follows_laws::<T>();
|
||||||
T::sample(|pa| {
|
T::sample(|pa| {
|
||||||
res += bind_respects_left_identity::<T, _, _>(|x| pa(x + 3), || 2);
|
res += bind_respects_left_identity::<T, _, _>(|x| pa(x + 3), || 2);
|
||||||
|
@ -26,12 +26,8 @@ impl R {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub trait Eqr: WeakFunctor {
|
pub trait Eqr<'a>: WeakFunctorA<'a> {
|
||||||
fn eqr<'a, A: PartialEq + Debug + 'a>(
|
fn eqr<A: PartialEq + Debug + 'a>(name: &'a str, left: Self::Fa<A>, right: Self::Fa<A>) -> R;
|
||||||
name: &'a str,
|
|
||||||
left: Self::F<'a, A>,
|
|
||||||
right: Self::F<'a, 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 {
|
||||||
@ -91,22 +87,22 @@ impl AddAssign<R> for R {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn fmap_respects_identity<'a, T: Functor<'a> + Eqr, A: 'a + Debug + PartialEq>(
|
pub fn fmap_respects_identity<'a, T: Functor<'a> + Eqr<'a>, A: 'a + Debug + PartialEq>(
|
||||||
fa0: impl Fn() -> T::F<'a, A>,
|
fa0: impl Fn() -> T::Fa<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())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn fmap_respects_composition<
|
pub fn fmap_respects_composition<
|
||||||
'a,
|
'a,
|
||||||
T: Functor<'a> + Eqr,
|
T: Functor<'a> + Eqr<'a>,
|
||||||
A: 'a,
|
A: 'a,
|
||||||
B: 'a,
|
B: 'a,
|
||||||
C: 'a + Debug + PartialEq,
|
C: 'a + Debug + PartialEq,
|
||||||
>(
|
>(
|
||||||
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::F<'a, A>,
|
fa0: impl Fn() -> T::Fa<A>,
|
||||||
) -> R {
|
) -> R {
|
||||||
T::eqr(
|
T::eqr(
|
||||||
"composition: fmap (f . g) == fmap f . fmap g",
|
"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>(
|
pub fn seq_respects_identity<'a, T: Applicative<'a> + Eqr<'a>, A: 'a + Debug + PartialEq>(
|
||||||
fa0: impl Fn() -> T::F<'a, A>,
|
fa0: impl Fn() -> T::Fa<A>,
|
||||||
) -> R {
|
) -> R {
|
||||||
T::eqr(
|
T::eqr(
|
||||||
"identity: pure id <*> v = v",
|
"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<
|
pub fn seq_respects_composition<
|
||||||
'a,
|
'a,
|
||||||
T: Applicative<'a> + Eqr,
|
T: Applicative<'a> + Eqr<'a>,
|
||||||
A: 'a,
|
A: 'a,
|
||||||
B: 'a,
|
B: 'a,
|
||||||
C: 'a + Debug + PartialEq,
|
C: 'a + Debug + PartialEq,
|
||||||
F: 'a + Fn(B) -> C,
|
F: 'a + Fn(B) -> C,
|
||||||
G: 'a + Fn(A) -> B,
|
G: 'a + Fn(A) -> B,
|
||||||
>(
|
>(
|
||||||
ff0: impl Fn() -> T::F<'a, F>,
|
ff0: impl Fn() -> T::Fa<F>,
|
||||||
fg0: impl Fn() -> T::F<'a, G>,
|
fg0: impl Fn() -> T::Fa<G>,
|
||||||
fa0: impl Fn() -> T::F<'a, A>,
|
fa0: impl Fn() -> T::Fa<A>,
|
||||||
) -> R {
|
) -> R {
|
||||||
T::eqr(
|
T::eqr(
|
||||||
"composition: pure (.) <*> u <*> v <*> w = u <*> (v <*> w)",
|
"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,
|
f: impl 'a + Fn(A) -> B,
|
||||||
a0: impl Fn() -> A,
|
a0: impl Fn() -> A,
|
||||||
) -> R {
|
) -> 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<
|
pub fn seq_respects_interchange<
|
||||||
'a,
|
'a,
|
||||||
T: Applicative<'a> + Eqr,
|
T: Applicative<'a> + Eqr<'a>,
|
||||||
A: 'a,
|
A: 'a,
|
||||||
B: 'a + Debug + PartialEq,
|
B: 'a + Debug + PartialEq,
|
||||||
F: 'a + Fn(A) -> B,
|
F: 'a + Fn(A) -> B,
|
||||||
>(
|
>(
|
||||||
ff0: impl Fn() -> T::F<'a, F>,
|
ff0: impl Fn() -> T::Fa<F>,
|
||||||
a0: impl 'a + Fn() -> A,
|
a0: impl 'a + Fn() -> A,
|
||||||
) -> R {
|
) -> R {
|
||||||
T::eqr(
|
T::eqr(
|
||||||
@ -181,13 +177,13 @@ pub fn seq_respects_interchange<
|
|||||||
|
|
||||||
pub fn seq_can_be_expressed_via_la2<
|
pub fn seq_can_be_expressed_via_la2<
|
||||||
'a,
|
'a,
|
||||||
T: Applicative<'a> + Eqr,
|
T: Applicative<'a> + Eqr<'a>,
|
||||||
A: 'a,
|
A: 'a,
|
||||||
B: 'a + Debug + PartialEq,
|
B: 'a + Debug + PartialEq,
|
||||||
F: 'a + Fn(A) -> B,
|
F: 'a + Fn(A) -> B,
|
||||||
>(
|
>(
|
||||||
ff0: impl Fn() -> T::F<'a, F>,
|
ff0: impl Fn() -> T::Fa<F>,
|
||||||
fa0: impl Fn() -> T::F<'a, A>,
|
fa0: impl Fn() -> T::Fa<A>,
|
||||||
) -> R {
|
) -> R {
|
||||||
T::eqr(
|
T::eqr(
|
||||||
"seq via la2: (<*>) = liftA2 id",
|
"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<
|
pub fn fmap_can_be_expressed_via_seq<
|
||||||
'a,
|
'a,
|
||||||
T: Applicative<'a> + Eqr,
|
T: Applicative<'a> + Eqr<'a>,
|
||||||
A: 'a,
|
A: 'a,
|
||||||
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::F<'a, A>,
|
fa0: impl Fn() -> T::Fa<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,12 +210,12 @@ pub fn fmap_can_be_expressed_via_seq<
|
|||||||
|
|
||||||
pub fn discard_can_be_expressed_via_seq_or_la2<
|
pub fn discard_can_be_expressed_via_seq_or_la2<
|
||||||
'a,
|
'a,
|
||||||
T: Applicative<'a> + Eqr,
|
T: Applicative<'a> + Eqr<'a>,
|
||||||
A: 'a,
|
A: 'a,
|
||||||
B: 'a + Debug + PartialEq,
|
B: 'a + Debug + PartialEq,
|
||||||
>(
|
>(
|
||||||
fa0: impl 'a + Fn() -> T::F<'a, A>,
|
fa0: impl 'a + Fn() -> T::Fa<A>,
|
||||||
fb0: impl 'a + Fn() -> T::F<'a, B>,
|
fb0: impl 'a + Fn() -> T::Fa<B>,
|
||||||
) -> R {
|
) -> R {
|
||||||
T::eqr(
|
T::eqr(
|
||||||
"discard via seq: u *> v = (id <$ u) <*> v",
|
"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>(
|
pub fn bind_respects_left_identity<'a, T: Monad<'a> + Eqr<'a>, A: 'a, B: 'a + Debug + PartialEq>(
|
||||||
f: impl 'a + Fn(A) -> T::F<'a, B>,
|
f: impl 'a + Fn(A) -> T::Fa<B>,
|
||||||
a0: impl Fn() -> A,
|
a0: impl Fn() -> A,
|
||||||
) -> R {
|
) -> R {
|
||||||
T::eqr(
|
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>(
|
pub fn bind_respects_right_identity<'a, T: Monad<'a> + Eqr<'a>, A: 'a + Debug + PartialEq>(
|
||||||
fa0: impl Fn() -> T::F<'a, A>,
|
fa0: impl Fn() -> T::Fa<A>,
|
||||||
) -> R {
|
) -> R {
|
||||||
T::eqr(
|
T::eqr(
|
||||||
"right identity: m >>= bind = m",
|
"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>(
|
pub fn bind_is_associative<'a, T: Monad<'a> + Eqr<'a>, A: 'a, B: 'a, C: 'a + Debug + PartialEq>(
|
||||||
f: impl 'a + Clone + Fn(B) -> T::F<'a, C>,
|
f: impl 'a + Clone + Fn(B) -> T::Fa<C>,
|
||||||
g: impl 'a + Clone + Fn(A) -> T::F<'a, B>,
|
g: impl 'a + Clone + Fn(A) -> T::Fa<B>,
|
||||||
fa0: impl 'a + Fn() -> T::F<'a, A>,
|
fa0: impl 'a + Fn() -> T::Fa<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",
|
||||||
@ -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<
|
pub fn seq_can_be_expressed_via_bind<
|
||||||
'a,
|
'a,
|
||||||
T: Monad<'a> + Eqr,
|
T: Monad<'a> + Eqr<'a>,
|
||||||
A: 'a,
|
A: 'a,
|
||||||
B: 'a + Debug + PartialEq,
|
B: 'a + Debug + PartialEq,
|
||||||
F: 'a + Fn(A) -> B,
|
F: 'a + Fn(A) -> B,
|
||||||
>(
|
>(
|
||||||
ff0: impl Fn() -> T::F<'a, F>,
|
ff0: impl Fn() -> T::Fa<F>,
|
||||||
fa0: impl 'a + Fn() -> T::F<'a, A>,
|
fa0: impl 'a + Fn() -> T::Fa<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)))",
|
||||||
@ -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,
|
f: impl 'a + Copy + Fn(A) -> B,
|
||||||
fa0: impl 'a + Fn() -> T::F<'a, A>,
|
fa0: impl 'a + Fn() -> T::Fa<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",
|
||||||
|
@ -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::F<'a, A>, event: impl 'b + FnOnce() -> String) -> T::F<'a, A>
|
fn after<'b, A: 'a>(fa: T::Fa<A>, event: impl 'b + FnOnce() -> String) -> T::Fa<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::F<'a, A>, event: impl 'b + FnOnce() -> String) -> T::F<'a, A>
|
fn before<'b, A: 'a>(fa: T::Fa<A>, event: impl 'b + FnOnce() -> String) -> T::Fa<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::F<'a, A>, event: impl 'b + FnOnce() -> String) -> T::F<'a, A>
|
fn wrapped<'b, A: 'a>(fa: T::Fa<A>, event: impl 'b + FnOnce() -> String) -> T::Fa<A>
|
||||||
where
|
where
|
||||||
'a: 'b;
|
'a: 'b;
|
||||||
}
|
}
|
||||||
|
@ -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::F<'a, A>, _event: impl 'b + FnOnce() -> String) -> T::F<'a, A> {
|
fn after<'b, A>(fa: T::Fa<A>, _event: impl 'b + FnOnce() -> String) -> T::Fa<A> {
|
||||||
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<A>, _event: impl 'b + FnOnce() -> String) -> T::Fa<A> {
|
||||||
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<A>, _event: impl 'b + FnOnce() -> String) -> T::Fa<A> {
|
||||||
fa
|
fa
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user