ApplicativeTuple lift lifetime

This commit is contained in:
AF 2023-05-26 09:09:27 +00:00
parent 0e3c1f5d45
commit dab754adf4
11 changed files with 27 additions and 55 deletions

View File

@ -150,11 +150,9 @@ pub trait ApplicativeLA2: Functor {
} }
/// 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: Functor { pub trait ApplicativeTuple<'a>: 'a + Functor {
/// 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: '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::F<'a, A>, Self::F<'a, B>)) -> Self::F<'a, (A, B)>;
where
Self: 'a;
} }
/// Equivalent of Haskell's `Applicative`. /// Equivalent of Haskell's `Applicative`.
@ -162,7 +160,7 @@ pub trait ApplicativeTuple: Functor {
/// ///
/// <https://hackage.haskell.org/package/base-4.18.0.0/docs/Control-Applicative.html> /// <https://hackage.haskell.org/package/base-4.18.0.0/docs/Control-Applicative.html>
pub trait Applicative<'a>: pub trait Applicative<'a>:
Pure + ApplicativeSeq + ApplicativeLA2 + ApplicativeTuple + ApplicativeSelect<'a> Pure + ApplicativeSeq + ApplicativeLA2 + 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::F<'a, A>, fb: Self::F<'a, B>) -> Self::F<'a, B> {

View File

@ -63,11 +63,10 @@ impl<U: ApplicativeLA2, V: ApplicativeLA2> ApplicativeLA2 for CompositionInstanc
} }
} }
impl<U: ApplicativeTuple, V: ApplicativeTuple> ApplicativeTuple for CompositionInstance<U, V> { impl<'a, U: ApplicativeTuple<'a>, V: ApplicativeTuple<'a>> ApplicativeTuple<'a>
fn tuple<'a, A: 'a, B: 'a>(fab: (Self::F<'a, A>, Self::F<'a, B>)) -> Self::F<'a, (A, B)> for CompositionInstance<U, V>
where
Self: 'a,
{ {
fn tuple<A: 'a, B: 'a>(fab: (Self::F<'a, A>, Self::F<'a, B>)) -> Self::F<'a, (A, B)> {
U::fmap(V::tuple, U::tuple(fab)) U::fmap(V::tuple, U::tuple(fab))
} }
} }

View File

@ -98,11 +98,8 @@ impl<E: Effect> ApplicativeLA2 for EffectInstance<E> {
} }
} }
impl<E: Effect> ApplicativeTuple for EffectInstance<E> { impl<'a, E: 'a + Effect> ApplicativeTuple<'a> for EffectInstance<E> {
fn tuple<'a, 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::F<'a, A>, Self::F<'a, B>)) -> Self::F<'a, (A, B)> {
where
Self: 'a,
{
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),

View File

@ -63,11 +63,8 @@ impl ApplicativeLA2 for FutureInstance {
} }
} }
impl ApplicativeTuple for FutureInstance { impl<'a> ApplicativeTuple<'a> for FutureInstance {
fn tuple<'a, 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::F<'a, A>, Self::F<'a, B>)) -> Self::F<'a, (A, B)> {
where
Self: 'a,
{
Box::pin(async { join!(fa, fb) }) Box::pin(async { join!(fa, fb) })
} }
} }

View File

@ -59,11 +59,8 @@ impl ApplicativeLA2 for LazyInstance {
} }
} }
impl ApplicativeTuple for LazyInstance { impl<'a> ApplicativeTuple<'a> for LazyInstance {
fn tuple<'a, 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::F<'a, A>, Self::F<'a, B>)) -> Self::F<'a, (A, B)> {
where
Self: 'a,
{
Box::new(|| (fa(), fb())) Box::new(|| (fa(), fb()))
} }
} }

View File

@ -63,11 +63,8 @@ impl ApplicativeLA2 for OptionInstance {
} }
} }
impl ApplicativeTuple for OptionInstance { impl<'a> ApplicativeTuple<'a> for OptionInstance {
fn tuple<'a, 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::F<'a, A>, Self::F<'a, B>)) -> Self::F<'a, (A, B)> {
where
Self: 'a,
{
Self::pure((fa?, fb?)) Self::pure((fa?, fb?))
} }
} }

View File

@ -75,11 +75,10 @@ impl<T: ApplicativeLA2, O: DeriveApplicative> ApplicativeLA2 for OverloadInstanc
} }
} }
impl<T: ApplicativeTuple, O: DeriveApplicative> ApplicativeTuple for OverloadInstance<T, O> { impl<'a, T: ApplicativeTuple<'a>, O: 'a + DeriveApplicative> ApplicativeTuple<'a>
fn tuple<'a, A: 'a, B: 'a>(fab: (Self::F<'a, A>, Self::F<'a, B>)) -> Self::F<'a, (A, B)> for OverloadInstance<T, O>
where
Self: 'a,
{ {
fn tuple<A: 'a, B: 'a>(fab: (Self::F<'a, A>, Self::F<'a, B>)) -> Self::F<'a, (A, B)> {
T::tuple(fab) T::tuple(fab)
} }
} }

View File

@ -75,11 +75,8 @@ impl<E> ApplicativeLA2 for ResultInstance<E> {
} }
} }
impl<E> ApplicativeTuple for ResultInstance<E> { impl<'a, E: 'a> ApplicativeTuple<'a> for ResultInstance<E> {
fn tuple<'a, 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::F<'a, A>, Self::F<'a, B>)) -> Self::F<'a, (A, B)> {
where
Self: 'a,
{
Self::pure((fa?, fb?)) Self::pure((fa?, fb?))
} }
} }

View File

@ -51,11 +51,8 @@ impl ApplicativeLA2 for SoloInstance {
} }
} }
impl ApplicativeTuple for SoloInstance { impl<'a> ApplicativeTuple<'a> for SoloInstance {
fn tuple<'a, 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::F<'a, A>, Self::F<'a, B>)) -> Self::F<'a, (A, B)> {
where
Self: 'a,
{
(fa, fb) (fa, fb)
} }
} }

View File

@ -178,11 +178,8 @@ impl ApplicativeLA2 for StacklessInstance {
} }
} }
impl ApplicativeTuple for StacklessInstance { impl<'a> ApplicativeTuple<'a> for StacklessInstance {
fn tuple<'a, 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::F<'a, A>, Self::F<'a, B>)) -> Self::F<'a, (A, B)> {
where
Self: 'a,
{
Self::_tuple_via_la2((fa, fb)) Self::_tuple_via_la2((fa, fb))
} }
} }

View File

@ -73,11 +73,8 @@ impl<E> ApplicativeLA2 for TryFutureInstance<E> {
} }
} }
impl<E> ApplicativeTuple for TryFutureInstance<E> { impl<'a, E: 'a> ApplicativeTuple<'a> for TryFutureInstance<E> {
fn tuple<'a, 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::F<'a, A>, Self::F<'a, B>)) -> Self::F<'a, (A, B)> {
where
Self: 'a,
{
Box::pin(async { try_join!(fa, fb) }) Box::pin(async { try_join!(fa, fb) })
} }
} }