Applicative lift lifetime

This commit is contained in:
AF 2023-05-26 08:58:28 +00:00
parent 906e159737
commit dde3af2386
13 changed files with 43 additions and 85 deletions

View File

@ -161,22 +161,16 @@ pub trait ApplicativeTuple: Functor {
/// Split into [`Pure`], [`ApplicativeSeq`], [`ApplicativeLA2`] and [`ApplicativeTuple`] due to Rust limitations.
///
/// <https://hackage.haskell.org/package/base-4.18.0.0/docs/Control-Applicative.html>
pub trait Applicative:
Pure + ApplicativeSeq + ApplicativeLA2 + ApplicativeTuple + ApplicativeSelect
pub trait Applicative<'a>:
'a + Pure + ApplicativeSeq + ApplicativeLA2 + ApplicativeTuple + ApplicativeSelect
{
/// Equivalent of Haskell's `*>`/`>>`.
fn discard_first<'a, A: 'a, B: 'a>(fa: Self::F<'a, A>, fb: Self::F<'a, B>) -> Self::F<'a, B>
where
Self: 'a,
{
fn discard_first<A: 'a, B: 'a>(fa: Self::F<'a, A>, fb: Self::F<'a, B>) -> Self::F<'a, B> {
Self::seq(Self::replace(fa, |b| b), fb)
}
/// Equivalent of Haskell's `<*`.
fn discard_second<'a, A: 'a, B: 'a>(fa: Self::F<'a, A>, fb: Self::F<'a, B>) -> Self::F<'a, A>
where
Self: 'a,
{
fn discard_second<A: 'a, B: 'a>(fa: Self::F<'a, A>, fb: Self::F<'a, B>) -> Self::F<'a, A> {
Self::la2(|a, _| a, fa, fb)
}
}
@ -184,7 +178,7 @@ pub trait Applicative:
/// Equivalent of Haskell's `Monad`.
///
/// <https://hackage.haskell.org/package/base-4.18.0.0/docs/Control-Monad.html>
pub trait Monad<'a>: 'a + Applicative {
pub trait Monad<'a>: Applicative<'a> {
/// Equivalent of Haskell's `>==`.
/// Due to Rust limitations, it's not a `function->function` conversion.
/// For that see [`derivations::bind`].

View File

@ -90,18 +90,12 @@ impl<U: ApplicativeSelect, V: Functor> ApplicativeSelect for CompositionInstance
}
}
impl<U: Applicative, V: Applicative> Applicative for CompositionInstance<U, V> {
fn discard_first<'a, A: 'a, B: 'a>(fa: Self::F<'a, A>, fb: Self::F<'a, B>) -> Self::F<'a, B>
where
Self: 'a,
{
impl<'a, U: Applicative<'a>, V: Applicative<'a>> Applicative<'a> for CompositionInstance<U, V> {
fn discard_first<A: 'a, B: 'a>(fa: Self::F<'a, A>, fb: Self::F<'a, B>) -> Self::F<'a, B> {
U::la2(|ua, ub| V::discard_first(ua, ub), fa, fb)
}
fn discard_second<'a, A: 'a, B: 'a>(fa: Self::F<'a, A>, fb: Self::F<'a, B>) -> Self::F<'a, A>
where
Self: 'a,
{
fn discard_second<A: 'a, B: 'a>(fa: Self::F<'a, A>, fb: Self::F<'a, B>) -> Self::F<'a, A> {
U::la2(|ua, ub| V::discard_second(ua, ub), fa, fb)
}
}

View File

@ -112,11 +112,8 @@ impl<E: Effect> ApplicativeTuple for EffectInstance<E> {
impl<E: Effect> ApplicativeSelect for EffectInstance<E> {}
impl<E: Effect> Applicative for EffectInstance<E> {
fn discard_first<'a, A: 'a, B: 'a>(fa: Self::F<'a, A>, fb: Self::F<'a, B>) -> Self::F<'a, B>
where
Self: 'a,
{
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> {
drop(fa.value);
WithEffect {
value: fb.value,
@ -124,10 +121,7 @@ impl<E: Effect> Applicative for EffectInstance<E> {
}
}
fn discard_second<'a, A: 'a, B: 'a>(fa: Self::F<'a, A>, fb: Self::F<'a, B>) -> Self::F<'a, A>
where
Self: 'a,
{
fn discard_second<A: 'a, B: 'a>(fa: Self::F<'a, A>, fb: Self::F<'a, B>) -> Self::F<'a, A> {
drop(fb.value);
WithEffect {
value: fa.value,

View File

@ -89,12 +89,12 @@ impl ApplicativeSelect for FutureInstance {
}
}
impl Applicative for FutureInstance {
fn discard_first<'a, A: 'a, B: 'a>(fa: Self::F<'a, A>, fb: Self::F<'a, B>) -> Self::F<'a, B> {
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> {
Box::pin(async { join!(fa, fb).1 })
}
fn discard_second<'a, 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::F<'a, A>, fb: Self::F<'a, B>) -> Self::F<'a, A> {
Box::pin(async { join!(fa, fb).0 })
}
}

View File

@ -70,13 +70,13 @@ impl ApplicativeTuple for LazyInstance {
impl ApplicativeSelect for LazyInstance {}
impl Applicative for LazyInstance {
fn discard_first<'a, A: 'a, B: 'a>(fa: Self::F<'a, A>, fb: Self::F<'a, B>) -> Self::F<'a, B> {
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> {
drop(fa);
fb
}
fn discard_second<'a, 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::F<'a, A>, fb: Self::F<'a, B>) -> Self::F<'a, A> {
drop(fb);
fa
}

View File

@ -74,13 +74,13 @@ impl ApplicativeTuple for OptionInstance {
impl ApplicativeSelect for OptionInstance {}
impl Applicative for OptionInstance {
fn discard_first<'a, A: 'a, B: 'a>(fa: Self::F<'a, A>, fb: Self::F<'a, B>) -> Self::F<'a, B> {
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> {
fa?;
fb
}
fn discard_second<'a, 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::F<'a, A>, fb: Self::F<'a, B>) -> Self::F<'a, A> {
fb?;
fa
}

View File

@ -86,18 +86,12 @@ impl<T: ApplicativeTuple, O: DeriveApplicative> ApplicativeTuple for OverloadIns
impl<T: ApplicativeTuple, O: DeriveApplicative> ApplicativeSelect for OverloadInstance<T, O> {}
impl<T: Applicative, O: DeriveApplicative> Applicative for OverloadInstance<T, O> {
fn discard_first<'a, A: 'a, B: 'a>(fa: Self::F<'a, A>, fb: Self::F<'a, B>) -> Self::F<'a, B>
where
Self: 'a,
{
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> {
T::discard_first(fa, fb)
}
fn discard_second<'a, A: 'a, B: 'a>(fa: Self::F<'a, A>, fb: Self::F<'a, B>) -> Self::F<'a, A>
where
Self: 'a,
{
fn discard_second<A: 'a, B: 'a>(fa: Self::F<'a, A>, fb: Self::F<'a, B>) -> Self::F<'a, A> {
T::discard_second(fa, fb)
}
}

View File

@ -86,19 +86,13 @@ impl<E> ApplicativeTuple for ResultInstance<E> {
impl<E> ApplicativeSelect for ResultInstance<E> {}
impl<E> Applicative for ResultInstance<E> {
fn discard_first<'a, A: 'a, B: 'a>(fa: Self::F<'a, A>, fb: Self::F<'a, B>) -> Self::F<'a, B>
where
Self: 'a,
{
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> {
fa?;
fb
}
fn discard_second<'a, A: 'a, B: 'a>(fa: Self::F<'a, A>, fb: Self::F<'a, B>) -> Self::F<'a, A>
where
Self: 'a,
{
fn discard_second<A: 'a, B: 'a>(fa: Self::F<'a, A>, fb: Self::F<'a, B>) -> Self::F<'a, A> {
fb?;
fa
}

View File

@ -62,13 +62,13 @@ impl ApplicativeTuple for SoloInstance {
impl ApplicativeSelect for SoloInstance {}
impl Applicative for SoloInstance {
fn discard_first<'a, A: 'a, B: 'a>(fa: Self::F<'a, A>, fb: Self::F<'a, B>) -> Self::F<'a, B> {
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> {
drop(fa);
fb
}
fn discard_second<'a, 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::F<'a, A>, fb: Self::F<'a, B>) -> Self::F<'a, A> {
drop(fb);
fa
}

View File

@ -189,11 +189,8 @@ impl ApplicativeTuple for StacklessInstance {
impl ApplicativeSelect for StacklessInstance {}
impl Applicative for StacklessInstance {
fn discard_first<'a, A: 'a, B: 'a>(fa: Self::F<'a, A>, fb: Self::F<'a, B>) -> Self::F<'a, B>
where
Self: 'a,
{
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> {
Stackless(Box::new(|takesb| {
Some(EvalTree::Composite(
Box::new(EvalTree::Atom(Box::new(|| fa.call(drop)))),
@ -202,10 +199,7 @@ impl Applicative for StacklessInstance {
}))
}
fn discard_second<'a, A: 'a, B: 'a>(fa: Self::F<'a, A>, fb: Self::F<'a, B>) -> Self::F<'a, A>
where
Self: 'a,
{
fn discard_second<A: 'a, B: 'a>(fa: Self::F<'a, A>, fb: Self::F<'a, B>) -> Self::F<'a, A> {
Stackless(Box::new(|takesa| {
Some(EvalTree::Composite(
Box::new(EvalTree::Atom(Box::new(|| fa.0(takesa)))),

View File

@ -101,18 +101,12 @@ impl<E> ApplicativeSelect for TryFutureInstance<E> {
}
}
impl<E> Applicative for TryFutureInstance<E> {
fn discard_first<'a, A: 'a, B: 'a>(fa: Self::F<'a, A>, fb: Self::F<'a, B>) -> Self::F<'a, B>
where
Self: 'a,
{
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> {
Box::pin(async { Ok(try_join!(fa, fb)?.1) })
}
fn discard_second<'a, A: 'a, B: 'a>(fa: Self::F<'a, A>, fb: Self::F<'a, B>) -> Self::F<'a, A>
where
Self: 'a,
{
fn discard_second<A: 'a, B: 'a>(fa: Self::F<'a, A>, fb: Self::F<'a, B>) -> Self::F<'a, A> {
Box::pin(async { Ok(try_join!(fa, fb)?.0) })
}
}

View File

@ -19,7 +19,7 @@ pub fn functor_follows_laws<T: Functor + FunctorTestSuite>() -> R {
res
}
pub fn applicative_follows_laws<T: Applicative + FunctorTestSuite>() -> R {
pub fn applicative_follows_laws<'a, T: Applicative<'a> + FunctorTestSuite>() -> R {
let mut res = functor_follows_laws::<T>();
T::sample(|pa| {
res += seq_respects_identity::<T, _>(|| pa(2));

View File

@ -115,7 +115,7 @@ pub fn fmap_respects_composition<
)
}
pub fn seq_respects_identity<'a, T: 'a + Applicative + Eqr, A: 'a + Debug + PartialEq>(
pub fn seq_respects_identity<'a, T: Applicative<'a> + Eqr, A: 'a + Debug + PartialEq>(
fa0: impl Fn() -> T::F<'a, A>,
) -> R {
T::eqr(
@ -127,7 +127,7 @@ pub fn seq_respects_identity<'a, T: 'a + Applicative + Eqr, A: 'a + Debug + Part
pub fn seq_respects_composition<
'a,
T: 'a + Applicative + Eqr,
T: Applicative<'a> + Eqr,
A: 'a,
B: 'a,
C: 'a + Debug + PartialEq,
@ -151,7 +151,7 @@ pub fn seq_respects_composition<
)
}
pub fn seq_is_homomorphic<'a, T: 'a + Applicative + Eqr, A: 'a, B: 'a + Debug + PartialEq>(
pub fn seq_is_homomorphic<'a, T: Applicative<'a> + Eqr, A: 'a, B: 'a + Debug + PartialEq>(
f: impl 'a + Fn(A) -> B,
a0: impl Fn() -> A,
) -> R {
@ -164,7 +164,7 @@ pub fn seq_is_homomorphic<'a, T: 'a + Applicative + Eqr, A: 'a, B: 'a + Debug +
pub fn seq_respects_interchange<
'a,
T: 'a + Applicative + Eqr,
T: Applicative<'a> + Eqr,
A: 'a,
B: 'a + Debug + PartialEq,
F: 'a + Fn(A) -> B,
@ -181,7 +181,7 @@ pub fn seq_respects_interchange<
pub fn seq_can_be_expressed_via_la2<
'a,
T: 'a + Applicative + Eqr,
T: Applicative<'a> + Eqr,
A: 'a,
B: 'a + Debug + PartialEq,
F: 'a + Fn(A) -> B,
@ -198,7 +198,7 @@ pub fn seq_can_be_expressed_via_la2<
pub fn fmap_can_be_expressed_via_seq<
'a,
T: 'a + Applicative + Eqr,
T: Applicative<'a> + Eqr,
A: 'a,
B: 'a + Debug + PartialEq,
>(
@ -214,7 +214,7 @@ pub fn fmap_can_be_expressed_via_seq<
pub fn discard_can_be_expressed_via_seq_or_la2<
'a,
T: 'a + Applicative + Eqr,
T: Applicative<'a> + Eqr,
A: 'a,
B: 'a + Debug + PartialEq,
>(