diff --git a/Changelog.md b/Changelog.md
--- a/Changelog.md
+++ b/Changelog.md
@@ -1,4 +1,10 @@
-# next
+# 0.3
+
+- Rename `OneTuple` to `Solo`
+- Add `Typeable`, `Data`, `MonadZip`, `Eq1`, `Ord1`, `Show1`, `Read1`,
+  `Generic` and `Generic1` instances
+
+# 0.2.2.1
 
 - Compatible with GHC-8.6
 
diff --git a/OneTuple.cabal b/OneTuple.cabal
--- a/OneTuple.cabal
+++ b/OneTuple.cabal
@@ -1,14 +1,16 @@
 cabal-version:      >=1.10
 name:               OneTuple
-version:            0.2.2.1
+version:            0.3
 synopsis:           Singleton Tuple
 category:           Data
 description:
-  This package provides a singleton tuple data type
+  This package is a compatibility package for a singleton data type
   .
-  > data OneTuple a = OneTuple a
+  > data Solo a = Solo a
   .
   Note: it's not a @newtype@
+  .
+  @Solo@ is available in @base-4.16@ (GHC-9.2).
 
 copyright:          (c) John Dorsey 2008
 license:            BSD3
@@ -30,8 +32,10 @@
    || ==8.2.2
    || ==8.4.4
    || ==8.6.5
-   || ==8.8.3
-   || ==8.10.1
+   || ==8.8.4
+   || ==8.10.4
+   || ==9.0.1
+   || ==9.2.1
 
 extra-source-files: Changelog.md
 
@@ -41,9 +45,45 @@
 
 library
   default-language: Haskell98
-  exposed-modules:  Data.Tuple.OneTuple
+  exposed-modules:
+    Data.Tuple.OneTuple
+    Data.Tuple.Solo
+
   hs-source-dirs:   src
-  build-depends:    base >=4.3 && <4.15
+  build-depends:    base >=4.3 && <4.17
 
+  if impl(ghc >=9.0)
+    build-depends: ghc-prim
+
   if !impl(ghc >=8.0)
-    build-depends: semigroups >=0.18.4 && <0.20
+    build-depends:
+        semigroups    >=0.18.4 && <0.20
+      , transformers  >=0.3    && <0.7
+
+    -- Ensure Data.Functor.Classes is always available
+    if impl(ghc >=7.10)
+      build-depends: transformers >=0.4.2.0
+
+    else
+      build-depends: transformers-compat >=0.5.1.0 && <0.7
+
+  if !impl(ghc >=9.2)
+    build-depends: base-orphans >=0.8.6
+
+  if !impl(ghc >=7.6)
+    build-depends: ghc-prim
+
+test-suite instances
+  type:             exitcode-stdio-1.0
+  default-language: Haskell98
+  hs-source-dirs:   test
+  main-is:          instances.hs
+  build-depends:
+      base
+    , OneTuple
+
+  if !impl(ghc >=8.0)
+    build-depends:
+        semigroups
+      , transformers
+      , transformers-compat
diff --git a/src/Data/Tuple/OneTuple.hs b/src/Data/Tuple/OneTuple.hs
--- a/src/Data/Tuple/OneTuple.hs
+++ b/src/Data/Tuple/OneTuple.hs
@@ -1,85 +1,31 @@
--- |OneTuple fills the /tuple gap/ with a singleton tuple.
---
--- OneTuple /does not support/ the usual parenthesized tuple syntax.
---
--- OneTuple
---
---   * has the expected laziness properties
---
---   * can be pattern-matched
---
---   * ships with instances for several standard type classes,
---     including all those supported by H98-standard tuples
+{-# LANGUAGE CPP             #-}
+#if __GLASGOW_HASKELL__ >= 708
+{-# LANGUAGE PatternSynonyms #-}
+#endif
+-- | This is a module to help migration from @OneTuple@ to @Solo@.
+-- Migrate to use "Data.Tuple" from @base-4.16@ or "Data.Tuple.Solo" with all GHCs.
 --
---   * requires no language extensions, except for hierarchical modules
-
-module Data.Tuple.OneTuple (OneTuple(OneTuple), only) where
-
-import Control.Applicative (Applicative (..))
-import Control.Monad       (ap)
-import Control.Monad.Fix   (MonadFix (..))
-import Data.Foldable       (Foldable (..))
-import Data.Ix             (Ix (..))
-import Data.Monoid         (Monoid (..))
-import Data.Semigroup      (Semigroup (..))
-import Data.Traversable    (Traversable (..))
-
--- |OneTuple is the singleton tuple data type.
-data OneTuple a
-    = OneTuple a  -- ^ singleton tuple constructor
-    deriving (Eq,Ord,Bounded,Show,Read)
-
--- |The 'only' function extracts the OneTuple's only member.
--- (Compare to 'fst' and 'snd'.)
-only :: OneTuple a -- ^ takes a singleton tuple argument
-     -> a          -- ^ returns the only element in the tuple
-only (OneTuple x) = x
-
-instance (Enum a) => Enum (OneTuple a) where
-    succ = fmap succ
-    pred = fmap pred
-    toEnum = pure . toEnum
-    fromEnum (OneTuple x) = fromEnum x
-
-instance (Ix a) => Ix (OneTuple a) where
-    range   (OneTuple x, OneTuple y) = map OneTuple (range (x,y))
-    index   (OneTuple x, OneTuple y) (OneTuple z) = index   (x,y) z
-    inRange (OneTuple x, OneTuple y) (OneTuple z) = inRange (x,y) z
-
-instance Foldable OneTuple where
-    fold (OneTuple m) = m
-    foldMap f (OneTuple x) = f x
-    foldr f b (OneTuple x) = f x b
-    foldl f a (OneTuple x) = f a x
-    foldr1 _f (OneTuple x) = x
-    foldl1 _f (OneTuple x) = x
-
-instance Traversable OneTuple where
-    traverse f (OneTuple x) = fmap OneTuple (f x)
-    sequenceA (OneTuple x) = fmap OneTuple x
-
-instance Functor OneTuple where
-    fmap f (OneTuple x) = OneTuple (f x)
-
-instance Applicative OneTuple where
-    pure = OneTuple
-
-    OneTuple f <*> OneTuple x = OneTuple (f x)
-    _ *> x = x
-    x <* _ = x
-
-instance Monad OneTuple where
-    return = pure
-    (>>) = (*>)
-    (OneTuple x) >>= f = f x
+-- The pattern synonym is provided for GHCs supporting pattern synonyms (7.8+)
+module Data.Tuple.OneTuple
+{-# DEPRECATED "Use Data.Tuple.Solo" #-}
+(
+    OneTuple,
+#if __GLASGOW_HASKELL__ >= 708
+    pattern OneTuple,
+#endif
+    only,
+) where
 
-instance (Semigroup a) => Semigroup (OneTuple a) where
-    OneTuple x <> OneTuple y = OneTuple (x <> y)
+import Data.Tuple.Solo
 
-instance (Monoid a) => Monoid (OneTuple a) where
-    mempty = OneTuple mempty
-    mappend (OneTuple x) (OneTuple y) = OneTuple (mappend x y)
+type OneTuple = Solo
 
-instance MonadFix OneTuple where
-    mfix f = let a = f (only a) in a
+only :: OneTuple a -> a
+only = getSolo
 
+#if __GLASGOW_HASKELL__ >= 708
+#if __GLASGOW_HASKELL__ >= 710
+pattern OneTuple :: a -> Solo a
+#endif
+pattern OneTuple a = Solo a
+#endif
diff --git a/src/Data/Tuple/Solo.hs b/src/Data/Tuple/Solo.hs
new file mode 100644
--- /dev/null
+++ b/src/Data/Tuple/Solo.hs
@@ -0,0 +1,208 @@
+{-# LANGUAGE CPP #-}
+{-# LANGUAGE DeriveDataTypeable #-}
+#if __GLASGOW_HASKELL__ >= 704
+{-# LANGUAGE Safe #-}
+#elif __GLASGOW_HASKELL__ >= 702
+{-# LANGUAGE Trustworthy #-}
+#endif
+#if __GLASGOW_HASKELL__ >=702
+{-# LANGUAGE DeriveGeneric #-}
+#endif
+
+-- | 'Solo' fills the /tuple gap/ with a singleton tuple.
+--
+-- 'Solo' /does not support/ the usual parenthesized tuple syntax.
+--
+-- 'Solo'
+--
+--   * has the expected laziness properties
+--
+--   * can be pattern-matched
+--
+--   * ships with instances for several standard type classes,
+--     including all those supported by H98-standard tuples
+--
+--   * requires no language extensions, except for hierarchical modules
+--
+-- Note: on GHC-9.0 'getSolo' is not a record selector.
+
+module Data.Tuple.Solo (
+    Solo(Solo),
+    getSolo,
+) where
+
+#ifdef MIN_VERSION_base_orphans
+import Data.Orphans ()
+#endif
+
+#if MIN_VERSION_base(4,16,0)
+import GHC.Tuple (Solo (Solo), getSolo)
+
+#elif MIN_VERSION_base(4,15,0)
+import GHC.Tuple (Solo (Solo))
+
+-- | The 'getSolo' function extracts the Solo's getSolo member.
+getSolo :: Solo a -> a
+getSolo (Solo x) = x
+
+#else
+
+#if MIN_VERSION_base(4,9,0)
+#define LIFTED_FUNCTOR_CLASSES 1
+#else
+#if MIN_VERSION_transformers(0,5,0)
+#define LIFTED_FUNCTOR_CLASSES 1
+#else
+#ifdef MIN_VERSION_transformers_compat
+#if MIN_VERSION_transformers_compat(0,5,0) && !(MIN_VERSION_transformers(0,4,0))
+#define LIFTED_FUNCTOR_CLASSES 1
+#endif
+#endif
+#endif
+#endif
+
+import Control.Applicative (Applicative (..))
+import Control.Monad       (ap)
+import Control.Monad.Fix   (MonadFix (..))
+import Data.Data           (Data)
+import Data.Foldable       (Foldable (..))
+import Data.Ix             (Ix (..))
+import Data.Monoid         (Monoid (..))
+import Data.Semigroup      (Semigroup (..))
+import Data.Traversable    (Traversable (..))
+import Data.Typeable       (Typeable)
+
+import Data.Functor.Classes (Eq1 (..), Ord1 (..), Show1 (..), Read1 (..))
+
+#if LIFTED_FUNCTOR_CLASSES
+#if MIN_VERSION_base(4,10,0)
+import Data.Functor.Classes (readData, readUnaryWith, liftReadListDefault, liftReadListPrecDefault)
+#else
+import Data.Functor.Classes (readsData, readsUnaryWith)
+#endif
+#endif
+
+#if MIN_VERSION_base(4,4,0)
+import GHC.Generics        (Generic, Generic1)
+#endif
+
+#if MIN_VERSION_base(4,4,0)
+import Control.Monad.Zip   (MonadZip (..))
+#endif
+
+-- | Solo is the singleton tuple data type.
+data Solo a = Solo { getSolo :: a }
+  deriving
+    ( Eq,Ord,Bounded,Read,Typeable,Data
+#if MIN_VERSION_base(4,4,0)
+    , Generic
+#if __GLASGOW_HASKELL__ >=706
+    , Generic1
+#endif
+#endif
+    )
+
+instance Show a => Show (Solo a) where
+  showsPrec d (Solo x) = showParen (d > 10) $
+      showString "Solo " . showsPrec 11 x
+
+instance (Enum a) => Enum (Solo a) where
+    succ = fmap succ
+    pred = fmap pred
+    toEnum = pure . toEnum
+    fromEnum (Solo x) = fromEnum x
+
+instance (Ix a) => Ix (Solo a) where
+    range   (Solo x, Solo y) = map Solo (range (x,y))
+    index   (Solo x, Solo y) (Solo z) = index   (x,y) z
+    inRange (Solo x, Solo y) (Solo z) = inRange (x,y) z
+
+instance Foldable Solo where
+    fold (Solo m) = m
+    foldMap f (Solo x) = f x
+    foldr f b (Solo x) = f x b
+    foldl f a (Solo x) = f a x
+    foldr1 _f (Solo x) = x
+    foldl1 _f (Solo x) = x
+
+    -- TODO: add rest of the methods
+#if MIN_VERSION_base(4,8,0)
+    null _ = False
+    length _ = 1
+
+    maximum = getSolo
+    minimum = getSolo
+    sum     = getSolo
+    product = getSolo
+
+    toList (Solo a) = [a]
+#endif
+
+instance Traversable Solo where
+    traverse f (Solo x) = fmap Solo (f x)
+    sequenceA (Solo x) = fmap Solo x
+
+
+instance Functor Solo where
+    fmap f (Solo x) = Solo (f x)
+
+instance Applicative Solo where
+    pure = Solo
+
+    Solo f <*> Solo x = Solo (f x)
+    _ *> x = x
+    x <* _ = x
+
+#if MIN_VERSION_base(4,10,0)
+    liftA2 f (Solo x) (Solo y) = Solo (f x y)
+#endif
+
+instance Monad Solo where
+    return = pure
+    (>>) = (*>)
+    Solo x >>= f = f x
+
+instance Semigroup a => Semigroup (Solo a) where
+    Solo x <> Solo y = Solo (x <> y)
+
+instance Monoid a => Monoid (Solo a) where
+    mempty = Solo mempty
+    mappend (Solo x) (Solo y) = Solo (mappend x y)
+
+instance MonadFix Solo where
+    mfix f = let a = f (getSolo a) in a
+
+#if MIN_VERSION_base(4,4,0)
+instance MonadZip Solo where
+    mzipWith f (Solo a) (Solo b) = Solo (f a b)
+#endif
+
+#ifdef LIFTED_FUNCTOR_CLASSES
+instance Eq1 Solo where
+  liftEq eq (Solo a) (Solo b) = a `eq` b
+
+instance Ord1 Solo where
+  liftCompare cmp (Solo a) (Solo b) = cmp a b
+
+instance Read1 Solo where
+#if MIN_VERSION_base(4,10,0)
+    liftReadPrec rp _ = readData (readUnaryWith rp "Solo" Solo)
+
+    liftReadListPrec = liftReadListPrecDefault
+    liftReadList     = liftReadListDefault
+#else
+    liftReadsPrec rp _ = readsData $ readsUnaryWith rp "Solo" Solo
+#endif
+
+instance Show1 Solo where
+    liftShowsPrec sp _ d (Solo x) = showParen (d > 10) $
+      showString "Solo " . sp 11 x
+
+#else
+instance Eq1 Solo where eq1 = (==)
+instance Ord1 Solo where compare1 = compare
+instance Read1 Solo where readsPrec1 = readsPrec
+instance Show1 Solo where showsPrec1 = showsPrec
+#endif
+
+#endif
diff --git a/test/instances.hs b/test/instances.hs
new file mode 100644
--- /dev/null
+++ b/test/instances.hs
@@ -0,0 +1,60 @@
+{-# LANGUAGE CPP #-}
+module Main where
+
+import Control.Applicative  (Applicative (..))
+import Control.Monad.Fix    (MonadFix (..))
+import Data.Data            (Data)
+import Data.Foldable        (Foldable (..))
+import Data.Functor.Classes (Eq1, Ord1, Read1, Show1)
+import Data.Ix              (Ix)
+import Data.Monoid          (Monoid (..))
+import Data.Semigroup       (Semigroup (..))
+import Data.Traversable     (Traversable (..))
+
+#if MIN_VERSION_base(4,4,0)
+import Control.Monad.Zip (MonadZip (..))
+#endif
+
+import Data.Tuple.Solo (Solo (..))
+
+main :: IO ()
+main = putStrLn "works"
+
+-------------------------------------------------------------------------------
+-- Instances
+-------------------------------------------------------------------------------
+
+tup1 :: Solo Char
+tup1 = Solo 'x'
+
+tup2 :: Solo String
+tup2 = Solo "test"
+
+hasEq :: Eq a => a -> a; hasEq x = x; testEq = hasEq tup1
+hasOrd :: Ord a => a -> a; hasOrd x = x; testOrd = hasOrd tup1
+hasBounded :: Bounded a => a -> a; hasBounded x = x; testBounded = hasBounded tup1
+hasEnum :: Enum a => a -> a; hasEnum x = x; testEnum = hasEnum tup1
+hasShow :: Show a => a -> a; hasShow x = x; testShow = hasShow tup1
+hasRead :: Read a => a -> a; hasRead x = x; testRead = hasRead tup1
+hasIx :: Ix a => a -> a; hasIx x = x; testIx = hasIx tup1
+
+hasMonoid :: Monoid a => a -> a; hasMonoid x = x; testMonoid = hasMonoid tup2
+hasSemigroup :: Semigroup a => a -> a; hasSemigroup x = x; testSemigroup = hasSemigroup tup2
+
+hasData :: Data a => a -> a; hasData x = x; testData = hasData tup2
+
+hasFunctor :: Functor f => f a -> f a; hasFunctor x = x; testFunctor = hasFunctor tup1
+hasFoldable :: Foldable f => f a -> f a; hasFoldable x = x; testFoldable = hasFoldable tup1
+hasTraversable :: Traversable f => f a -> f a; hasTraversable x = x; testTraversable = hasTraversable tup1
+hasApplicative :: Applicative f => f a -> f a; hasApplicative x = x; testApplicative = hasApplicative tup1
+hasMonad :: Monad f => f a -> f a; hasMonad x = x; testMonad = hasMonad tup1
+hasMonadFix :: MonadFix f => f a -> f a; hasMonadFix x = x; testMonadFix = hasMonadFix tup1
+
+#if MIN_VERSION_base(4,4,0)
+hasMonadZip :: MonadZip f => f a -> f a; hasMonadZip x = x; testMonadZip = hasMonadZip tup1
+#endif
+
+hasEq1 :: Eq1 f => f a -> f a; hasEq1 x = x; testEq1 = hasEq1 tup1
+hasOrd1 :: Ord1 f => f a -> f a; hasOrd1 x = x; testOrd1 = hasOrd1 tup1
+hasShow1 :: Show1 f => f a -> f a; hasShow1 x = x; testShow1 = hasShow1 tup1
+hasRead1 :: Read1 f => f a -> f a; hasRead1 x = x; testRead1 = hasRead1 tup1
