diff --git a/src/func.rs b/src/func.rs
index c0dbf29..176c4c3 100644
--- a/src/func.rs
+++ b/src/func.rs
@@ -7,7 +7,9 @@ pub mod test_suite;
 pub mod tests;
 
 pub trait WeakFunctor {
-    type F<'a, A: 'a>: 'a where Self: 'a;
+    type F<'a, A: 'a>: 'a
+    where
+        Self: 'a;
 }
 
 /// Rust-specific implementation of [Functor], respecting `move` semantics.
@@ -112,9 +114,18 @@ pub trait ApplicativeLA2: Functor {
     {
         Self::la2(|f, a| f(a), ff, fa)
     }
+    fn _tuple<'a, A: 'a, B: 'a>((fa, fb): (Self::F<'a, A>, Self::F<'a, B>)) -> Self::F<'a, (A, B)> {
+        Self::la2(|a, b| (a, b), fa, fb)
+    }
 }
 
-pub trait Applicative: Functor + ApplicativeSeq + ApplicativeLA2 {
+pub trait ApplicativeTuple: Functor {
+    fn tuple<'a, A: 'a, B: 'a>(fab: (Self::F<'a, A>, Self::F<'a, B>)) -> Self::F<'a, (A, B)>
+    where
+        Self: 'a;
+}
+
+pub trait Applicative: Functor + ApplicativeSeq + ApplicativeLA2 + ApplicativeTuple {
     fn pure<'a, A: 'a>(a: A) -> Self::F<'a, A>;
 
     fn discard_first<'a, A: 'a, B: 'a>(fa: Self::F<'a, A>, fb: Self::F<'a, B>) -> Self::F<'a, B>
diff --git a/src/func/classes/future.rs b/src/func/classes/future.rs
index 9b2b1a6..53866ca 100644
--- a/src/func/classes/future.rs
+++ b/src/func/classes/future.rs
@@ -48,6 +48,15 @@ impl ApplicativeLA2 for FutureClass {
     }
 }
 
+impl ApplicativeTuple for FutureClass {
+    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,
+    {
+        Box::pin(async { join!(fa, fb) })
+    }
+}
+
 impl Applicative for FutureClass {
     fn pure<'a, A: 'a>(a: A) -> Self::F<'a, A> {
         Box::pin(async { a })
diff --git a/src/func/classes/lazy.rs b/src/func/classes/lazy.rs
index ace391b..ccd927c 100644
--- a/src/func/classes/lazy.rs
+++ b/src/func/classes/lazy.rs
@@ -41,6 +41,15 @@ impl ApplicativeLA2 for LazyClass {
     }
 }
 
+impl ApplicativeTuple for LazyClass {
+    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,
+    {
+        Box::new(|| (fa(), fb()))
+    }
+}
+
 impl Applicative for LazyClass {
     fn pure<'a, A: 'a>(a: A) -> Self::F<'a, A> {
         Box::new(|| a)
diff --git a/src/func/classes/option.rs b/src/func/classes/option.rs
index 3b6c751..50d0d22 100644
--- a/src/func/classes/option.rs
+++ b/src/func/classes/option.rs
@@ -35,6 +35,15 @@ impl ApplicativeLA2 for OptionClass {
     }
 }
 
+impl ApplicativeTuple for OptionClass {
+    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,
+    {
+        Self::pure((fa?, fb?))
+    }
+}
+
 impl Applicative for OptionClass {
     fn pure<'a, A: 'a>(a: A) -> Self::F<'a, A> {
         Some(a)
diff --git a/src/func/classes/result.rs b/src/func/classes/result.rs
index 08e0d74..bb5f21f 100644
--- a/src/func/classes/result.rs
+++ b/src/func/classes/result.rs
@@ -35,6 +35,15 @@ impl<E> ApplicativeLA2 for ResultClass<E> {
     }
 }
 
+impl<E> ApplicativeTuple for ResultClass<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,
+    {
+        Self::pure((fa?, fb?))
+    }
+}
+
 impl<E> Applicative for ResultClass<E> {
     fn pure<'a, A: 'a>(a: A) -> Self::F<'a, A> {
         Ok(a)
diff --git a/src/func/classes/solo.rs b/src/func/classes/solo.rs
index 07f0ae2..12c0a39 100644
--- a/src/func/classes/solo.rs
+++ b/src/func/classes/solo.rs
@@ -40,6 +40,15 @@ impl ApplicativeLA2 for SoloClass {
     }
 }
 
+impl ApplicativeTuple for SoloClass {
+    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,
+    {
+        (fa, fb)
+    }
+}
+
 impl Applicative for SoloClass {
     fn pure<'a, A: 'a>(a: A) -> Self::F<'a, A> {
         a
diff --git a/src/func/classes/stackless.rs b/src/func/classes/stackless.rs
index 657e27e..63f3be4 100644
--- a/src/func/classes/stackless.rs
+++ b/src/func/classes/stackless.rs
@@ -163,6 +163,15 @@ impl ApplicativeLA2 for StacklessClass {
     }
 }
 
+impl ApplicativeTuple for StacklessClass {
+    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,
+    {
+        Self::_tuple((fa, fb))
+    }
+}
+
 impl Applicative for StacklessClass {
     fn pure<'a, A: 'a>(a: A) -> Self::F<'a, A> {
         Stackless::from(a)