diff --git a/CHANGELOG.md b/CHANGELOG.md
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,3 +1,8 @@
+Version 1.5.4
+---------------
+* Deriving `Data` and `Typeable` for all declared data types.
+* Bumped the upper bound of the `template-haskell` dependency.
+
 Version 1.5.3.1
 ---------------
 * Bumped the upper bound of the `template-haskell` dependency.
diff --git a/rank2classes.cabal b/rank2classes.cabal
--- a/rank2classes.cabal
+++ b/rank2classes.cabal
@@ -1,5 +1,5 @@
 name:                rank2classes
-version:             1.5.3.1
+version:             1.5.4
 synopsis:            standard type constructor class hierarchy, only with methods of rank 2 types
 description:
   A mirror image of the standard type constructor class hierarchy rooted in 'Functor', except with methods of rank 2
@@ -16,7 +16,7 @@
 category:            Control, Data, Generics
 build-type:          Custom
 cabal-version:       >=1.10
-tested-with:         GHC==9.2.2, GHC==9.0.1, GHC==8.10.4, GHC==8.8.4, GHC==8.6.5, GHC==8.4.4, GHC==8.2.2
+tested-with:         GHC==9.8.2, GHC==9.6.4, GHC==9.4.8, GHC==9.2.8, GHC==9.0.2, GHC==8.10.7
 extra-source-files:  README.md, CHANGELOG.md, test/MyModule.lhs
 source-repository head
   type:              git
@@ -44,7 +44,7 @@
                        data-functor-logistic < 0.1
 
   if flag(use-template-haskell)
-    build-depends: template-haskell >= 2.11 && < 2.23
+    build-depends: template-haskell >= 2.11 && < 2.24
     exposed-modules: Rank2.TH
 
 test-suite doctests
diff --git a/src/Rank2.hs b/src/Rank2.hs
--- a/src/Rank2.hs
+++ b/src/Rank2.hs
@@ -7,6 +7,7 @@
 -- the less standard classes 'Apply', 'Distributive', and 'Logistic'.
 {-# LANGUAGE DefaultSignatures, InstanceSigs, KindSignatures, PolyKinds, Rank2Types #-}
 {-# LANGUAGE ScopedTypeVariables, StandaloneDeriving, TypeOperators, UndecidableInstances #-}
+{-# LANGUAGE DeriveDataTypeable #-}
 {-# LANGUAGE EmptyCase #-}
 {-# LANGUAGE TypeApplications #-}
 module Rank2 (
@@ -31,6 +32,7 @@
 import qualified Data.Functor.Logistic as Rank1
 import qualified Data.Distributive as Rank1
 import Data.Coerce (coerce)
+import Data.Data (Data, Typeable)
 import Data.Semigroup (Semigroup(..))
 import Data.Monoid (Monoid(..))
 import Data.Functor.Const (Const(..))
@@ -75,7 +77,7 @@
    traverse f = sequence . fmap (Rank1.Compose . f)
    sequence = traverse Rank1.getCompose
 -- | Wrapper for functions that map the argument constructor type
-newtype Arrow p q a = Arrow{apply :: p a -> q a}
+newtype Arrow p q a = Arrow{apply :: p a -> q a} deriving Typeable
 
 type (~>) = Arrow
 ($) :: Arrow p q a -> p a -> q a
@@ -189,23 +191,25 @@
 distributeWithTraversable = cotraverseTraversable
 
 -- | A rank-2 equivalent of @()@, a zero-element tuple
-data Empty f = Empty deriving (Eq, Ord, Show)
+data Empty f = Empty deriving (Eq, Ord, Show, Data, Typeable)
 
 -- | A rank-2 tuple of only one element
-newtype Only a f = Only {fromOnly :: f a} deriving (Eq, Ord, Show)
+newtype Only a f = Only {fromOnly :: f a} deriving (Eq, Ord, Show, Data, Typeable)
 
 -- | Equivalent of 'Data.Functor.Identity' for rank 2 data types
-newtype Identity g f = Identity {runIdentity :: g f} deriving (Eq, Ord, Show)
+newtype Identity g f = Identity {runIdentity :: g f} deriving (Eq, Ord, Show, Data, Typeable)
 
 -- | Equivalent of 'Data.Functor.Compose' for rank 2 data types
-newtype Compose g p q = Compose {getCompose :: g (Rank1.Compose p q)}
+newtype Compose g p q = Compose {getCompose :: g (Rank1.Compose p q)} deriving Typeable
 
 deriving instance Eq (g (Rank1.Compose p q)) => Eq (Compose g p q)
 deriving instance Ord (g (Rank1.Compose p q)) => Ord (Compose g p q)
 deriving instance Show (g (Rank1.Compose p q)) => Show (Compose g p q)
+deriving instance (Typeable k1, Typeable k, Typeable g, Typeable (p :: k -> Type), Typeable (q :: k1 -> k),
+                   Data (g (Rank1.Compose p q))) => Data (Compose g p q)
 
 -- | A nested parametric type represented as a rank-2 type
-newtype Flip g a f = Flip {unFlip :: g (f a)} deriving (Eq, Ord, Show)
+newtype Flip g a f = Flip {unFlip :: g (f a)} deriving (Eq, Ord, Show, Data, Typeable)
 
 instance Semigroup (g (f a)) => Semigroup (Flip g a f) where
    Flip x <> Flip y = Flip (x <> y)
@@ -218,7 +222,7 @@
    f <$> Flip g = Flip (f Rank1.<$> g)
 
 instance Rank1.Applicative g => Rank2.Apply (Flip g a) where
-   Flip g <*> Flip h = Flip (apply Rank1.<$> g Rank1.<*> h)
+   Flip g <*> Flip h = Flip (Rank1.liftA2 apply g h)
 
 instance Rank1.Applicative g => Rank2.Applicative (Flip g a) where
    pure f = Flip (Rank1.pure f)
