From dab754adf46e7f809facbccae6805f86b557987c Mon Sep 17 00:00:00 2001
From: timofey <tim@ongoteam.yaconnect.com>
Date: Fri, 26 May 2023 09:09:27 +0000
Subject: [PATCH] `ApplicativeTuple` lift lifetime

---
 src/func.rs                       | 8 +++-----
 src/func/instances/composition.rs | 9 ++++-----
 src/func/instances/effect.rs      | 7 ++-----
 src/func/instances/future.rs      | 7 ++-----
 src/func/instances/lazy.rs        | 7 ++-----
 src/func/instances/option.rs      | 7 ++-----
 src/func/instances/overload.rs    | 9 ++++-----
 src/func/instances/result.rs      | 7 ++-----
 src/func/instances/solo.rs        | 7 ++-----
 src/func/instances/stackless.rs   | 7 ++-----
 src/func/instances/tryfuture.rs   | 7 ++-----
 11 files changed, 27 insertions(+), 55 deletions(-)

diff --git a/src/func.rs b/src/func.rs
index cfb166d..63a8288 100644
--- a/src/func.rs
+++ b/src/func.rs
@@ -150,11 +150,9 @@ pub trait ApplicativeLA2: Functor {
 }
 
 /// 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.
-    fn tuple<'a, A: 'a, B: 'a>(fab: (Self::F<'a, A>, Self::F<'a, B>)) -> Self::F<'a, (A, B)>
-    where
-        Self: 'a;
+    fn tuple<A: 'a, B: 'a>(fab: (Self::F<'a, A>, Self::F<'a, B>)) -> Self::F<'a, (A, B)>;
 }
 
 /// 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>
 pub trait Applicative<'a>:
-    Pure + ApplicativeSeq + ApplicativeLA2 + ApplicativeTuple + ApplicativeSelect<'a>
+    Pure + ApplicativeSeq + ApplicativeLA2 + ApplicativeTuple<'a> + ApplicativeSelect<'a>
 {
     /// 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> {
diff --git a/src/func/instances/composition.rs b/src/func/instances/composition.rs
index 679193d..5d9d5eb 100644
--- a/src/func/instances/composition.rs
+++ b/src/func/instances/composition.rs
@@ -63,11 +63,10 @@ impl<U: ApplicativeLA2, V: ApplicativeLA2> ApplicativeLA2 for CompositionInstanc
     }
 }
 
-impl<U: ApplicativeTuple, V: ApplicativeTuple> ApplicativeTuple for CompositionInstance<U, V> {
-    fn tuple<'a, A: 'a, B: 'a>(fab: (Self::F<'a, A>, Self::F<'a, B>)) -> Self::F<'a, (A, B)>
-    where
-        Self: 'a,
-    {
+impl<'a, U: ApplicativeTuple<'a>, V: ApplicativeTuple<'a>> ApplicativeTuple<'a>
+    for CompositionInstance<U, V>
+{
+    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))
     }
 }
diff --git a/src/func/instances/effect.rs b/src/func/instances/effect.rs
index 1c063c7..76e8440 100644
--- a/src/func/instances/effect.rs
+++ b/src/func/instances/effect.rs
@@ -98,11 +98,8 @@ impl<E: Effect> ApplicativeLA2 for EffectInstance<E> {
     }
 }
 
-impl<E: Effect> ApplicativeTuple 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)>
-    where
-        Self: 'a,
-    {
+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)> {
         WithEffect {
             value: (fa.value, fb.value),
             effect: E::e_seq(fa.effect, fb.effect),
diff --git a/src/func/instances/future.rs b/src/func/instances/future.rs
index 8eee7a9..2eaa390 100644
--- a/src/func/instances/future.rs
+++ b/src/func/instances/future.rs
@@ -63,11 +63,8 @@ impl ApplicativeLA2 for FutureInstance {
     }
 }
 
-impl ApplicativeTuple for FutureInstance {
-    fn tuple<'a, A: 'a, B: 'a>((fa, fb): (Self::F<'a, A>, Self::F<'a, B>)) -> Self::F<'a, (A, B)>
-    where
-        Self: 'a,
-    {
+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)> {
         Box::pin(async { join!(fa, fb) })
     }
 }
diff --git a/src/func/instances/lazy.rs b/src/func/instances/lazy.rs
index 759f837..5b2afab 100644
--- a/src/func/instances/lazy.rs
+++ b/src/func/instances/lazy.rs
@@ -59,11 +59,8 @@ impl ApplicativeLA2 for LazyInstance {
     }
 }
 
-impl ApplicativeTuple for LazyInstance {
-    fn tuple<'a, A: 'a, B: 'a>((fa, fb): (Self::F<'a, A>, Self::F<'a, B>)) -> Self::F<'a, (A, B)>
-    where
-        Self: 'a,
-    {
+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)> {
         Box::new(|| (fa(), fb()))
     }
 }
diff --git a/src/func/instances/option.rs b/src/func/instances/option.rs
index 119a5c6..1d9afb1 100644
--- a/src/func/instances/option.rs
+++ b/src/func/instances/option.rs
@@ -63,11 +63,8 @@ impl ApplicativeLA2 for OptionInstance {
     }
 }
 
-impl ApplicativeTuple for OptionInstance {
-    fn tuple<'a, A: 'a, B: 'a>((fa, fb): (Self::F<'a, A>, Self::F<'a, B>)) -> Self::F<'a, (A, B)>
-    where
-        Self: 'a,
-    {
+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)> {
         Self::pure((fa?, fb?))
     }
 }
diff --git a/src/func/instances/overload.rs b/src/func/instances/overload.rs
index 2688fde..48360ca 100644
--- a/src/func/instances/overload.rs
+++ b/src/func/instances/overload.rs
@@ -75,11 +75,10 @@ impl<T: ApplicativeLA2, O: DeriveApplicative> ApplicativeLA2 for OverloadInstanc
     }
 }
 
-impl<T: ApplicativeTuple, O: DeriveApplicative> ApplicativeTuple for OverloadInstance<T, O> {
-    fn tuple<'a, A: 'a, B: 'a>(fab: (Self::F<'a, A>, Self::F<'a, B>)) -> Self::F<'a, (A, B)>
-    where
-        Self: 'a,
-    {
+impl<'a, T: ApplicativeTuple<'a>, O: 'a + DeriveApplicative> ApplicativeTuple<'a>
+    for OverloadInstance<T, O>
+{
+    fn tuple<A: 'a, B: 'a>(fab: (Self::F<'a, A>, Self::F<'a, B>)) -> Self::F<'a, (A, B)> {
         T::tuple(fab)
     }
 }
diff --git a/src/func/instances/result.rs b/src/func/instances/result.rs
index 4a1722d..2c5c39f 100644
--- a/src/func/instances/result.rs
+++ b/src/func/instances/result.rs
@@ -75,11 +75,8 @@ impl<E> ApplicativeLA2 for ResultInstance<E> {
     }
 }
 
-impl<E> ApplicativeTuple 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)>
-    where
-        Self: 'a,
-    {
+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)> {
         Self::pure((fa?, fb?))
     }
 }
diff --git a/src/func/instances/solo.rs b/src/func/instances/solo.rs
index f973b4b..9ebf8b6 100644
--- a/src/func/instances/solo.rs
+++ b/src/func/instances/solo.rs
@@ -51,11 +51,8 @@ impl ApplicativeLA2 for SoloInstance {
     }
 }
 
-impl ApplicativeTuple for SoloInstance {
-    fn tuple<'a, A: 'a, B: 'a>((fa, fb): (Self::F<'a, A>, Self::F<'a, B>)) -> Self::F<'a, (A, B)>
-    where
-        Self: 'a,
-    {
+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)> {
         (fa, fb)
     }
 }
diff --git a/src/func/instances/stackless.rs b/src/func/instances/stackless.rs
index 4d6de93..37e9661 100644
--- a/src/func/instances/stackless.rs
+++ b/src/func/instances/stackless.rs
@@ -178,11 +178,8 @@ impl ApplicativeLA2 for StacklessInstance {
     }
 }
 
-impl ApplicativeTuple for StacklessInstance {
-    fn tuple<'a, A: 'a, B: 'a>((fa, fb): (Self::F<'a, A>, Self::F<'a, B>)) -> Self::F<'a, (A, B)>
-    where
-        Self: 'a,
-    {
+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)> {
         Self::_tuple_via_la2((fa, fb))
     }
 }
diff --git a/src/func/instances/tryfuture.rs b/src/func/instances/tryfuture.rs
index c22f24c..fc0a105 100644
--- a/src/func/instances/tryfuture.rs
+++ b/src/func/instances/tryfuture.rs
@@ -73,11 +73,8 @@ impl<E> ApplicativeLA2 for TryFutureInstance<E> {
     }
 }
 
-impl<E> ApplicativeTuple 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)>
-    where
-        Self: 'a,
-    {
+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)> {
         Box::pin(async { try_join!(fa, fb) })
     }
 }