diff --git a/CHANGELOG.md b/CHANGELOG.md
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,3 +1,10 @@
+# 0.4
+* Due to [GHC bug #5289](http://ghc.haskell.org/trac/ghc/ticket/5289), projects that depend on the `double-conversion` library (such as `text-format`, a dependency of `text-show`) may break due to GHC incorrectly linking against libstdc++. Therefore, `text-show` was changed so that it does not depend on `text-format` by default. This behavior can be changed by using the `-ftext-format` flag when using `cabal`.
+* Add `showbZonedTime` to `Text.Show.Text.Data.Time` (and corresponding `Show` instance for `ZonedTime`)
+* Expose `showbMaskingState` (is was already there, I just forgot to export it)
+* If using GHC 7.6 or earlier, depend on tagged so that Data.Proxy can be used
+* Refactor code to use Template Haskell derivations when possible
+
 # 0.3.1.0
 * Add `showList` and `showListLazy`
 * Don't use showbListDefault to show `containers` data types
diff --git a/src/Text/Show/Text/Control/Applicative.hs b/src/Text/Show/Text/Control/Applicative.hs
--- a/src/Text/Show/Text/Control/Applicative.hs
+++ b/src/Text/Show/Text/Control/Applicative.hs
@@ -1,4 +1,4 @@
-{-# LANGUAGE NoImplicitPrelude, OverloadedStrings #-}
+{-# LANGUAGE NoImplicitPrelude, TemplateHaskell #-}
 {-# OPTIONS_GHC -fno-warn-orphans #-}
 -----------------------------------------------------------------------------
 -- |
@@ -13,26 +13,19 @@
 ----------------------------------------------------------------------------
 module Text.Show.Text.Control.Applicative (showbZipListPrec) where
 
-import Control.Applicative (ZipList(..))
+import Control.Applicative (ZipList)
 
 import Data.Text.Lazy.Builder (Builder)
 
-import GHC.Show (appPrec)
-
 import Prelude hiding (Show)
 
-import Text.Show.Text.Class (Show(showb, showbPrec), showbParen)
+import Text.Show.Text.Class (Show(showbPrec))
 import Text.Show.Text.Data.List ()
-import Text.Show.Text.Utils ((<>), s)
+import Text.Show.Text.TH.Internal (deriveShow)
 
 -- | Convert a 'ZipList' to a 'Builder' with the given precedence.
 showbZipListPrec :: Show a => Int -> ZipList a -> Builder
-showbZipListPrec p (ZipList zl) = showbParen (p > appPrec) $
-        "ZipList {getZipList = "
-     <> showb zl
-     <> s '}'
+showbZipListPrec = showbPrec
 {-# INLINE showbZipListPrec #-}
 
-instance Show a => Show (ZipList a) where
-    showbPrec = showbZipListPrec
-    {-# INLINE showbPrec #-}
+$(deriveShow ''ZipList)
diff --git a/src/Text/Show/Text/Control/Concurrent.hs b/src/Text/Show/Text/Control/Concurrent.hs
--- a/src/Text/Show/Text/Control/Concurrent.hs
+++ b/src/Text/Show/Text/Control/Concurrent.hs
@@ -1,4 +1,4 @@
-{-# LANGUAGE NoImplicitPrelude, OverloadedStrings #-}
+{-# LANGUAGE NoImplicitPrelude, TemplateHaskell #-}
 {-# OPTIONS_GHC -fno-warn-orphans #-}
 -----------------------------------------------------------------------------
 -- |
@@ -19,14 +19,13 @@
 
 import           Data.Text.Lazy.Builder (Builder, fromString)
 
-import           GHC.Conc (BlockReason(..), ThreadId, ThreadStatus(..))
-import           GHC.Show (appPrec)
+import           GHC.Conc (BlockReason, ThreadId, ThreadStatus)
 
 import qualified Prelude as P
 import           Prelude hiding (Show)
 
-import           Text.Show.Text.Class (Show(showb, showbPrec), showbParen)
-import           Text.Show.Text.Utils ((<>))
+import           Text.Show.Text.Class (Show(showb, showbPrec))
+import           Text.Show.Text.TH.Internal (deriveShow)
 
 -- | Convert a 'ThreadId' to a 'Builder' with the given precedence.
 showbThreadIdPrec :: Int -> ThreadId -> Builder
@@ -35,31 +34,17 @@
 
 -- | Convert a 'ThreadStatus' to a 'Builder' with the given precedence.
 showbThreadStatusPrec :: Int -> ThreadStatus -> Builder
-showbThreadStatusPrec _ ThreadRunning  = "ThreadRunning"
-showbThreadStatusPrec _ ThreadFinished = "ThreadFinished"
-showbThreadStatusPrec p (ThreadBlocked br)
-    = showbParen (p > appPrec) $ "ThreadBlocked " <> showbBlockReason br
-showbThreadStatusPrec _ ThreadDied     = "ThreadDied"
+showbThreadStatusPrec = showbPrec
 {-# INLINE showbThreadStatusPrec #-}
 
 -- | Convert a 'BlockReason' to a 'Builder'.
 showbBlockReason :: BlockReason -> Builder
-showbBlockReason BlockedOnMVar        = "BlockedOnMVar"
-showbBlockReason BlockedOnBlackHole   = "BlockedOnBlackHole"
-showbBlockReason BlockedOnException   = "BlockedOnException"
-showbBlockReason BlockedOnSTM         = "BlockedOnSTM"
-showbBlockReason BlockedOnForeignCall = "BlockedOnForeignCall"
-showbBlockReason BlockedOnOther       = "BlockedOnOther"
+showbBlockReason = showb
 {-# INLINE showbBlockReason #-}
 
 instance Show ThreadId where
     showbPrec = showbThreadIdPrec
     {-# INLINE showbPrec #-}
 
-instance Show ThreadStatus where
-    showbPrec = showbThreadStatusPrec
-    {-# INLINE showbPrec #-}
-
-instance Show BlockReason where
-    showb = showbBlockReason
-    {-# INLINE showb #-}
+$(deriveShow ''ThreadStatus)
+$(deriveShow ''BlockReason)
diff --git a/src/Text/Show/Text/Control/Exception.hs b/src/Text/Show/Text/Control/Exception.hs
--- a/src/Text/Show/Text/Control/Exception.hs
+++ b/src/Text/Show/Text/Control/Exception.hs
@@ -1,4 +1,4 @@
-{-# LANGUAGE CPP, NoImplicitPrelude, OverloadedStrings #-}
+{-# LANGUAGE CPP, NoImplicitPrelude, OverloadedStrings, TemplateHaskell #-}
 {-# OPTIONS_GHC -fno-warn-orphans #-}
 -----------------------------------------------------------------------------
 -- |
@@ -32,6 +32,7 @@
   , showbRecSelError
   , showbRecUpdError
   , showbErrorCall
+  , showbMaskingState
   ) where
 
 import           Control.Exception.Base
@@ -43,6 +44,7 @@
 import           Prelude hiding (Show)
 
 import           Text.Show.Text.Class (Show(showb, showbPrec))
+import           Text.Show.Text.TH.Internal (deriveShow)
 import           Text.Show.Text.Utils ((<>))
 
 -- | Convert a 'SomeException' value to a 'Builder' with the given precedence.
@@ -156,9 +158,7 @@
 
 -- | Convert a 'MaskingState' to a 'Builder'.
 showbMaskingState :: MaskingState -> Builder
-showbMaskingState Unmasked              = "Unmasked"
-showbMaskingState MaskedInterruptible   = "MaskedInterruptible"
-showbMaskingState MaskedUninterruptible = "MaskedUninterruptible"
+showbMaskingState = showb
 {-# INLINE showbMaskingState #-}
 
 instance Show SomeException where
@@ -235,6 +235,4 @@
     showb = showbErrorCall
     {-# INLINE showb #-}
 
-instance Show MaskingState where
-    showb = showbMaskingState
-    {-# INLINE showb #-}
+$(deriveShow ''MaskingState)
diff --git a/src/Text/Show/Text/Data/Bool.hs b/src/Text/Show/Text/Data/Bool.hs
--- a/src/Text/Show/Text/Data/Bool.hs
+++ b/src/Text/Show/Text/Data/Bool.hs
@@ -1,4 +1,4 @@
-{-# LANGUAGE NoImplicitPrelude, OverloadedStrings #-}
+{-# LANGUAGE TemplateHaskell #-}
 {-# OPTIONS_GHC -fno-warn-orphans #-}
 -----------------------------------------------------------------------------
 -- |
@@ -13,18 +13,14 @@
 ----------------------------------------------------------------------------
 module Text.Show.Text.Data.Bool (showbBool) where
 
-import Data.Text.Buildable (build)
 import Data.Text.Lazy.Builder (Builder)
 
-import Prelude hiding (Show)
-
-import Text.Show.Text.Class (Show(showb))
+import Text.Show.Text.Class (showb)
+import Text.Show.Text.TH.Internal (deriveShow)
 
 -- | Convert a 'Bool' to a 'Builder'.
 showbBool :: Bool -> Builder
-showbBool = build
+showbBool = showb
 {-# INLINE showbBool #-}
 
-instance Show Bool where
-    showb = showbBool
-    {-# INLINE showb #-}
+$(deriveShow ''Bool)
diff --git a/src/Text/Show/Text/Data/ByteString.hs b/src/Text/Show/Text/Data/ByteString.hs
--- a/src/Text/Show/Text/Data/ByteString.hs
+++ b/src/Text/Show/Text/Data/ByteString.hs
@@ -1,6 +1,6 @@
 {-# LANGUAGE CPP, NoImplicitPrelude #-}
 #if !(MIN_VERSION_bytestring(0,10,0))
-{-# LANGUAGE OverloadedStrings #-}
+{-# LANGUAGE TemplateHaskell #-}
 #endif
 {-# OPTIONS_GHC -fno-warn-orphans #-}
 -----------------------------------------------------------------------------
@@ -37,14 +37,8 @@
 
 import           Text.Show.Text.Class (Show(showb, showbPrec))
 
--- Imports needed for older versions of bytestring
 #if !(MIN_VERSION_bytestring(0,10,0))
-import qualified Data.ByteString.Lazy.Internal as BL
-
-import           GHC.Show (appPrec, appPrec1)
-
-import           Text.Show.Text.Class (showbParen)
-import           Text.Show.Text.Utils ((<>), s)
+import           Text.Show.Text.TH.Internal (deriveShow)
 #endif
 
 -- | Convert a strict 'BS.ByteString' to a 'Builder'.
@@ -68,12 +62,7 @@
 #if MIN_VERSION_bytestring(0,10,0)
 showbByteStringLazyPrec _ = fromString . P.show
 #else
-showbByteStringLazyPrec _ BL.Empty         = "Empty"
-showbByteStringLazyPrec p (BL.Chunk bs bl) = showbParen (p > appPrec) $
-        "Chunk "
-     <> showbPrec appPrec1 bs
-     <> s ' '
-     <> showbPrec appPrec1 bl
+showbByteStringLazyPrec = showbPrec
 #endif
 {-# INLINE showbByteStringLazyPrec #-}
 
@@ -88,9 +77,13 @@
     showb = showbByteStringStrict
     {-# INLINE showb #-}
 
+#if MIN_VERSION_bytestring(0,10,0)
 instance Show BL.ByteString where
     showbPrec = showbByteStringLazyPrec
     {-# INLINE showbPrec #-}
+#else
+$(deriveShow ''BL.ByteString)
+#endif
 
 #if MIN_VERSION_bytestring(0,10,4)
 instance Show ShortByteString where
diff --git a/src/Text/Show/Text/Data/Char.hs b/src/Text/Show/Text/Data/Char.hs
--- a/src/Text/Show/Text/Data/Char.hs
+++ b/src/Text/Show/Text/Data/Char.hs
@@ -1,4 +1,4 @@
-{-# LANGUAGE NoImplicitPrelude, OverloadedStrings #-}
+{-# LANGUAGE NoImplicitPrelude, OverloadedStrings, TemplateHaskell #-}
 {-# OPTIONS_GHC -fno-warn-orphans #-}
 -----------------------------------------------------------------------------
 -- |
@@ -20,14 +20,15 @@
     ) where
 
 import Data.Array (Array, (!), listArray)
-import Data.Char (GeneralCategory(..), isDigit, ord)
+import Data.Char (GeneralCategory, isDigit, ord)
 import Data.Monoid (mempty)
-import Data.Text.Buildable (build)
 import Data.Text.Lazy.Builder (Builder)
 
 import Prelude hiding (Show)
 
 import Text.Show.Text.Class (Show(..))
+import Text.Show.Text.Data.Integral (showbIntPrec)
+import Text.Show.Text.TH.Internal (deriveShow)
 import Text.Show.Text.Utils ((<>), s)
 
 -- | A table of ASCII control characters that needs to be escaped with a backslash.
@@ -46,7 +47,7 @@
 
 -- | Convert a 'Char' to a 'Builder' (without single quotes).
 showbLitChar :: Char -> Builder
-showbLitChar c | c > '\DEL' = s '\\' <> build (ord c)
+showbLitChar c | c > '\DEL' = s '\\' <> showbIntPrec 0 (ord c)
 showbLitChar '\DEL'         = "\\DEL"
 showbLitChar '\\'           = "\\\\"
 showbLitChar c | c >= ' '   = s c
@@ -72,42 +73,13 @@
 showbLitString ('\SO':'H':cs) = "\\SO\\&H" <> showbLitString cs
 showbLitString ('"':cs)       = "\\\"" <> showbLitString cs
 showbLitString (c:d:cs)
-    | c > '\DEL' && isDigit d = s '\\' <> build (ord c) <> "\\&" <> s d <> showbLitString cs
+    | c > '\DEL' && isDigit d = s '\\' <> showbIntPrec 0 (ord c) <> "\\&" <> s d <> showbLitString cs
 showbLitString (c:cs)         = showbLitChar c <> showbLitString cs
 {-# INLINE showbLitString #-}
 
 -- | Convert a 'GeneralCategory' to a 'Builder'.
 showbGeneralCategory :: GeneralCategory -> Builder
-showbGeneralCategory UppercaseLetter      = "UppercaseLetter"
-showbGeneralCategory LowercaseLetter      = "LowercaseLetter"
-showbGeneralCategory TitlecaseLetter      = "TitlecaseLetter"
-showbGeneralCategory ModifierLetter       = "ModifierLetter"
-showbGeneralCategory OtherLetter          = "OtherLetter"
-showbGeneralCategory NonSpacingMark       = "NonSpacingMark"
-showbGeneralCategory SpacingCombiningMark = "SpacingCombiningMark"
-showbGeneralCategory EnclosingMark        = "EnclosingMark"
-showbGeneralCategory DecimalNumber        = "DecimalNumber"
-showbGeneralCategory LetterNumber         = "LetterNumber"
-showbGeneralCategory OtherNumber          = "OtherNumber"
-showbGeneralCategory ConnectorPunctuation = "ConnectorPunctuation"
-showbGeneralCategory DashPunctuation      = "DashPunctuation"
-showbGeneralCategory OpenPunctuation      = "OpenPunctuation"
-showbGeneralCategory ClosePunctuation     = "ClosePunctuation"
-showbGeneralCategory InitialQuote         = "InitialQuote"
-showbGeneralCategory FinalQuote           = "FinalQuote"
-showbGeneralCategory OtherPunctuation     = "OtherPunctuation"
-showbGeneralCategory MathSymbol           = "MathSymbol"
-showbGeneralCategory CurrencySymbol       = "CurrencySymbol" 
-showbGeneralCategory ModifierSymbol       = "ModifierSymbol"
-showbGeneralCategory OtherSymbol          = "OtherSymbol"
-showbGeneralCategory Space                = "Space"
-showbGeneralCategory LineSeparator        = "LineSeparator"
-showbGeneralCategory ParagraphSeparator   = "ParagraphSeparator"
-showbGeneralCategory Control              = "Control"
-showbGeneralCategory Format               = "Format"
-showbGeneralCategory Surrogate            = "Surrogate"
-showbGeneralCategory PrivateUse           = "PrivateUse"
-showbGeneralCategory NotAssigned          = "NotAssigned"
+showbGeneralCategory = showb
 {-# INLINE showbGeneralCategory #-}
 
 instance Show Char where
@@ -117,6 +89,4 @@
     showbList = showbString
     {-# INLINE showbList #-}
 
-instance Show GeneralCategory where
-    showb = showbGeneralCategory
-    {-# INLINE showb #-}
+$(deriveShow ''GeneralCategory)
diff --git a/src/Text/Show/Text/Data/Containers.hs b/src/Text/Show/Text/Data/Containers.hs
--- a/src/Text/Show/Text/Data/Containers.hs
+++ b/src/Text/Show/Text/Data/Containers.hs
@@ -1,4 +1,4 @@
-{-# LANGUAGE NoImplicitPrelude, OverloadedStrings #-}
+{-# LANGUAGE NoImplicitPrelude, OverloadedStrings, TemplateHaskell #-}
 {-# OPTIONS -fno-warn-orphans #-}
 -----------------------------------------------------------------------------
 -- |
@@ -34,7 +34,7 @@
 import           Data.Sequence (Seq)
 import qualified Data.Set as Set
 import           Data.Set (Set)
-import           Data.Tree (Tree(..))
+import           Data.Tree (Tree)
 
 import           GHC.Show (appPrec)
 
@@ -44,7 +44,8 @@
 import           Text.Show.Text.Data.Integral ()
 import           Text.Show.Text.Data.List ()
 import           Text.Show.Text.Data.Tuple ()
-import           Text.Show.Text.Utils ((<>), s)
+import           Text.Show.Text.TH.Internal (deriveShow)
+import           Text.Show.Text.Utils ((<>))
 
 -- | Convert an 'IntMap' into a 'Builder' with the given precedence.
 showbIntMapPrec :: Show v => Int -> IntMap v -> Builder
@@ -78,12 +79,7 @@
 
 -- | Convert a 'Tree' into a 'Builder' with the given precedence.
 showbTreePrec :: Show a => Int -> Tree a -> Builder
-showbTreePrec p (Node rl sf) = showbParen (p > appPrec) $
-        "Node {rootLabel = "
-     <> showb rl
-     <> ", subForest = "
-     <> showb sf
-     <> s '}'
+showbTreePrec = showbPrec
 {-# INLINE showbTreePrec #-}
 
 instance Show v => Show (IntMap v) where
@@ -106,6 +102,4 @@
     showbPrec = showbSetPrec
     {-# INLINE showbPrec #-}
 
-instance Show a => Show (Tree a) where
-    showbPrec = showbTreePrec
-    {-# INLINE showbPrec #-}
+$(deriveShow ''Tree)
diff --git a/src/Text/Show/Text/Data/Data.hs b/src/Text/Show/Text/Data/Data.hs
--- a/src/Text/Show/Text/Data/Data.hs
+++ b/src/Text/Show/Text/Data/Data.hs
@@ -1,4 +1,4 @@
-{-# LANGUAGE NoImplicitPrelude, OverloadedStrings #-}
+{-# LANGUAGE NoImplicitPrelude, TemplateHaskell #-}
 {-# OPTIONS_GHC -fno-warn-orphans #-}
 -----------------------------------------------------------------------------
 -- |
@@ -19,37 +19,24 @@
     , showbFixity
     ) where
 
-import Data.Data (Constr, ConstrRep(..), DataRep(..), DataType, Fixity(..),
-                  dataTypeName, dataTypeRep, showConstr)
+import Data.Data (Constr, ConstrRep, DataRep, DataType, Fixity, showConstr)
 import Data.Text.Lazy.Builder (Builder, fromString)
 
-import GHC.Show (appPrec, appPrec1)
-
 import Prelude hiding (Show)
 
-import Text.Show.Text.Class (Show(showb, showbPrec), showbParen)
-import Text.Show.Text.Data.Char (showbChar)
-import Text.Show.Text.Data.Integral (showbIntPrec, showbIntegerPrec, showbRatioPrec)
+import Text.Show.Text.Class (Show(showb, showbPrec))
+import Text.Show.Text.Data.Integral ()
 import Text.Show.Text.Data.List ()
-import Text.Show.Text.Utils ((<>), s)
+import Text.Show.Text.TH.Internal (deriveShow)
 
 -- | Convert a 'DataType' to a 'Builder' with the given precedence.
 showbDataTypePrec :: Int -> DataType -> Builder
-showbDataTypePrec p dt = showbParen (p > appPrec) $
-       "DataType {tycon = "
-    <> showb (dataTypeName dt)
-    <> ", datarep = "
-    <> showb (dataTypeRep  dt)
-    <> s '}'
+showbDataTypePrec = showbPrec
 {-# INLINE showbDataTypePrec #-}
 
 -- | Convert a 'DataRep' to a 'Builder' with the given precedence.
 showbDataRepPrec :: Int -> DataRep -> Builder
-showbDataRepPrec p (AlgRep cs) = showbParen (p > appPrec) $ "AlgRep " <> showb cs
-showbDataRepPrec _ IntRep      = "IntRep"
-showbDataRepPrec _ FloatRep    = "FloatRep"
-showbDataRepPrec _ CharRep     = "CharRep"
-showbDataRepPrec _ NoRep       = "NoRep"
+showbDataRepPrec = showbPrec
 {-# INLINE showbDataRepPrec #-}
 
 -- | Convert a 'Constr' to a 'Builder'.
@@ -59,38 +46,19 @@
 
 -- | Convert a 'Fixity' value to a 'Builder'.
 showbFixity :: Fixity -> Builder
-showbFixity Prefix = "Prefix"
-showbFixity Infix  = "Infix"
+showbFixity = showb
 {-# INLINE showbFixity #-}
 
 -- | Convert a 'ConstrRep' to a 'Builder' with the given precedence.
 showbConstrRepPrec :: Int -> ConstrRep -> Builder
-showbConstrRepPrec p (AlgConstr ci)
-    = showbParen (p > appPrec) $ "AlgConstr "   <> showbIntPrec appPrec1 ci
-showbConstrRepPrec p (IntConstr i)
-    = showbParen (p > appPrec) $ "IntConstr "   <> showbIntegerPrec appPrec1 i
-showbConstrRepPrec p (FloatConstr r)
-    = showbParen (p > appPrec) $ "FloatConstr " <> showbRatioPrec appPrec1 r
-showbConstrRepPrec p (CharConstr c)
-    = showbParen (p > appPrec) $ "CharConstr "  <> showbChar c
+showbConstrRepPrec = showbPrec
 {-# INLINE showbConstrRepPrec #-}
 
-instance Show DataType where
-    showbPrec = showbDataTypePrec
-    {-# INLINE showbPrec #-}
-
-instance Show DataRep where
-    showbPrec = showbDataRepPrec
-    {-# INLINE showbPrec #-}
+$(deriveShow ''DataType)
+$(deriveShow ''DataRep)
+$(deriveShow ''ConstrRep)
+$(deriveShow ''Fixity)
 
 instance Show Constr where
     showb = showbConstr
-    {-# INLINE showb #-}
-
-instance Show ConstrRep where
-    showbPrec = showbConstrRepPrec
-    {-# INLINE showbPrec #-}
-
-instance Show Fixity where
-    showb = showbFixity
     {-# INLINE showb #-}
diff --git a/src/Text/Show/Text/Data/Either.hs b/src/Text/Show/Text/Data/Either.hs
--- a/src/Text/Show/Text/Data/Either.hs
+++ b/src/Text/Show/Text/Data/Either.hs
@@ -1,4 +1,4 @@
-{-# LANGUAGE NoImplicitPrelude, OverloadedStrings #-}
+{-# LANGUAGE NoImplicitPrelude, TemplateHaskell #-}
 {-# OPTIONS_GHC -fno-warn-orphans #-}
 -----------------------------------------------------------------------------
 -- |
@@ -15,19 +15,14 @@
 
 import Data.Text.Lazy.Builder (Builder)
 
-import GHC.Show (appPrec, appPrec1)
-
 import Prelude hiding (Show)
 
-import Text.Show.Text.Class (Show(showbPrec), showbParen)
-import Text.Show.Text.Utils ((<>))
+import Text.Show.Text.Class (Show(showbPrec))
+import Text.Show.Text.TH.Internal (deriveShow)
 
 -- | Convert a 'Either' value to a 'Builder' with the given precedence.
 showbEitherPrec :: (Show a, Show b) => Int -> Either a b -> Builder
-showbEitherPrec p (Left a)  = showbParen (p > appPrec) $ "Left "  <> showbPrec appPrec1 a
-showbEitherPrec p (Right b) = showbParen (p > appPrec) $ "Right " <> showbPrec appPrec1 b
+showbEitherPrec = showbPrec
 {-# INLINE showbEitherPrec #-}
 
-instance (Show a, Show b) => Show (Either a b) where
-    showbPrec = showbEitherPrec
-    {-# INLINE showbPrec #-}
+$(deriveShow ''Either)
diff --git a/src/Text/Show/Text/Data/Integral.hs b/src/Text/Show/Text/Data/Integral.hs
--- a/src/Text/Show/Text/Data/Integral.hs
+++ b/src/Text/Show/Text/Data/Integral.hs
@@ -1,4 +1,7 @@
 {-# LANGUAGE CPP, MagicHash, NoImplicitPrelude, OverloadedStrings #-}
+#if !defined(TEXT_FORMAT)
+{-# LANGUAGE BangPatterns, UnboxedTuples #-}
+#endif
 {-# OPTIONS_GHC -fno-warn-orphans #-}
 -----------------------------------------------------------------------------
 -- |
@@ -35,7 +38,6 @@
 import           Data.Int (Int8, Int16, Int32, Int64)
 import           Data.Monoid (mempty)
 import           Data.Ratio (Ratio, numerator, denominator)
-import           Data.Text.Buildable (build)
 import           Data.Text.Lazy.Builder (Builder)
 import           Data.Word (Word, Word8, Word16, Word32, Word64)
 
@@ -53,6 +55,16 @@
 import           Text.Show.Text.Class (Show(showb, showbPrec), showbParen)
 import           Text.Show.Text.Utils ((<>), s)
 
+#if defined(TEXT_FORMAT)
+import           Data.Text.Buildable (build)
+#else
+import           GHC.Base (quotInt, remInt)
+import           GHC.Integer.GMP.Internals (Integer(..))
+import           GHC.Num (quotRemInteger)
+
+import           Text.Show.Text.Utils (i2d)
+#endif
+
 -- | Convert an 'Int' to a 'Builder' with the given precedence.
 showbIntPrec :: Int -> Int -> Builder
 showbIntPrec (I# p) n'@(I# n)
@@ -170,6 +182,131 @@
 showbWord64 :: Word64 -> Builder
 showbWord64 = build
 {-# INLINE showbWord64 #-}
+
+#if !defined(TEXT_FORMAT)
+build :: Integral a => a -> Builder
+build = decimal
+{-# INLINE build #-}
+
+decimal :: Integral a => a -> Builder
+{-# SPECIALIZE decimal :: Int -> Builder #-}
+{-# SPECIALIZE decimal :: Int8 -> Builder #-}
+{-# SPECIALIZE decimal :: Int16 -> Builder #-}
+{-# SPECIALIZE decimal :: Int32 -> Builder #-}
+{-# SPECIALIZE decimal :: Int64 -> Builder #-}
+{-# SPECIALIZE decimal :: Word -> Builder #-}
+{-# SPECIALIZE decimal :: Word8 -> Builder #-}
+{-# SPECIALIZE decimal :: Word16 -> Builder #-}
+{-# SPECIALIZE decimal :: Word32 -> Builder #-}
+{-# SPECIALIZE decimal :: Word64 -> Builder #-}
+{-# RULES "decimal/Integer" decimal = integer 10 :: Integer -> Builder #-}
+decimal i
+    | i < 0     = minus <> go (-i)
+    | otherwise = go i
+  where
+    go n | n < 10    = digit n
+         | otherwise = go (n `quot` 10) <> digit (n `rem` 10)
+{-# NOINLINE[0] decimal #-}
+
+hexadecimal :: Integral a => a -> Builder
+{-# SPECIALIZE hexadecimal :: Int -> Builder #-}
+{-# SPECIALIZE hexadecimal :: Int8 -> Builder #-}
+{-# SPECIALIZE hexadecimal :: Int16 -> Builder #-}
+{-# SPECIALIZE hexadecimal :: Int32 -> Builder #-}
+{-# SPECIALIZE hexadecimal :: Int64 -> Builder #-}
+{-# SPECIALIZE hexadecimal :: Word -> Builder #-}
+{-# SPECIALIZE hexadecimal :: Word8 -> Builder #-}
+{-# SPECIALIZE hexadecimal :: Word16 -> Builder #-}
+{-# SPECIALIZE hexadecimal :: Word32 -> Builder #-}
+{-# SPECIALIZE hexadecimal :: Word64 -> Builder #-}
+{-# RULES "hexadecimal/Integer" hexadecimal = integer 16 :: Integer -> Builder #-}
+hexadecimal i
+    | i < 0     = minus <> go (-i)
+    | otherwise = go i
+  where
+    go n | n < 16    = hexDigit n
+         | otherwise = go (n `quot` 16) <> hexDigit (n `rem` 16)
+{-# NOINLINE[0] hexadecimal #-}
+
+digit :: Integral a => a -> Builder
+digit n = s $! i2d (fromIntegral n)
+{-# INLINE digit #-}
+
+hexDigit :: Integral a => a -> Builder
+hexDigit n
+    | n <= 9    = s $! i2d (fromIntegral n)
+    | otherwise = s $! toEnum (fromIntegral n + 87)
+{-# INLINE hexDigit #-}
+
+minus :: Builder
+minus = s '-'
+{-# INLINE minus #-}
+
+int :: Int -> Builder
+int = decimal
+{-# INLINE int #-}
+
+data T = T !Integer !Int
+
+integer :: Int -> Integer -> Builder
+integer 10 (S# i#) = decimal (I# i#)
+integer 16 (S# i#) = hexadecimal (I# i#)
+integer base i
+    | i < 0     = minus <> go (-i)
+    | otherwise = go i
+  where
+    go n | n < maxInt = int (fromInteger n)
+         | otherwise  = putH (splitf (maxInt * maxInt) n)
+
+    splitf p n
+      | p > n       = [n]
+      | otherwise   = splith p (splitf (p*p) n)
+
+    splith p (n:ns) = case n `quotRemInteger` p of
+                        (# q,r #) | q > 0     -> q : r : splitb p ns
+                                  | otherwise -> r : splitb p ns
+    splith _ _      = error "splith: the impossible happened."
+
+    splitb p (n:ns) = case n `quotRemInteger` p of
+                        (# q,r #) -> q : r : splitb p ns
+    splitb _ _      = []
+
+    T maxInt10 maxDigits10 =
+        until ((>mi) . (*10) . fstT) (\(T n d) -> T (n*10) (d+1)) (T 10 1)
+      where mi = fromIntegral (maxBound :: Int)
+    T maxInt16 maxDigits16 =
+        until ((>mi) . (*16) . fstT) (\(T n d) -> T (n*16) (d+1)) (T 16 1)
+      where mi = fromIntegral (maxBound :: Int)
+
+    fstT (T a _) = a
+
+    maxInt | base == 10 = maxInt10
+           | otherwise  = maxInt16
+    maxDigits | base == 10 = maxDigits10
+              | otherwise  = maxDigits16
+
+    putH (n:ns) = case n `quotRemInteger` maxInt of
+                    (# x,y #)
+                        | q > 0     -> int q <> pblock r <> putB ns
+                        | otherwise -> int r <> putB ns
+                        where q = fromInteger x
+                              r = fromInteger y
+    putH _ = error "putH: the impossible happened"
+
+    putB (n:ns) = case n `quotRemInteger` maxInt of
+                    (# x,y #) -> pblock q <> pblock r <> putB ns
+                        where q = fromInteger x
+                              r = fromInteger y
+    putB _ = mempty
+
+    pblock = loop maxDigits
+      where
+        loop !d !n
+            | d == 1    = digit n
+            | otherwise = loop (d-1) q <> digit r
+            where q = n `quotInt` base
+                  r = n `remInt` base
+#endif
 
 instance Show Int where
     showbPrec = showbIntPrec
diff --git a/src/Text/Show/Text/Data/Maybe.hs b/src/Text/Show/Text/Data/Maybe.hs
--- a/src/Text/Show/Text/Data/Maybe.hs
+++ b/src/Text/Show/Text/Data/Maybe.hs
@@ -1,4 +1,4 @@
-{-# LANGUAGE NoImplicitPrelude, OverloadedStrings #-}
+{-# LANGUAGE NoImplicitPrelude, TemplateHaskell #-}
 {-# OPTIONS_GHC -fno-warn-orphans #-}
 -----------------------------------------------------------------------------
 -- |
@@ -15,19 +15,14 @@
 
 import Data.Text.Lazy.Builder (Builder)
 
-import GHC.Show (appPrec, appPrec1)
-
 import Prelude hiding (Show)
 
-import Text.Show.Text.Class (Show(showbPrec), showbParen)
-import Text.Show.Text.Utils ((<>))
+import Text.Show.Text.Class (Show(showbPrec))
+import Text.Show.Text.TH.Internal (deriveShow)
 
 -- | Convert a 'Maybe' value to a 'Builder' with the given precedence.
 showbMaybePrec :: Show a => Int -> Maybe a -> Builder
-showbMaybePrec _ Nothing  = "Nothing"
-showbMaybePrec p (Just a) = showbParen (p > appPrec) $ "Just " <> showbPrec appPrec1 a
+showbMaybePrec = showbPrec
 {-# INLINE showbMaybePrec #-}
 
-instance Show a => Show (Maybe a) where
-    showbPrec = showbMaybePrec
-    {-# INLINE showbPrec #-}
+$(deriveShow ''Maybe)
diff --git a/src/Text/Show/Text/Data/Monoid.hs b/src/Text/Show/Text/Data/Monoid.hs
--- a/src/Text/Show/Text/Data/Monoid.hs
+++ b/src/Text/Show/Text/Data/Monoid.hs
@@ -1,4 +1,4 @@
-{-# LANGUAGE NoImplicitPrelude, OverloadedStrings #-}
+{-# LANGUAGE NoImplicitPrelude, TemplateHaskell #-}
 {-# OPTIONS_GHC -fno-warn-orphans #-}
 -----------------------------------------------------------------------------
 -- |
@@ -21,99 +21,55 @@
     , showbSumPrec
     ) where
 
-import Data.Monoid (All(..), Any(..), Dual(..), First(..),
-                    Last(..), Product(..), Sum(..))
+import Data.Monoid (All, Any, Dual, First, Last, Product, Sum)
 import Data.Text.Lazy.Builder (Builder)
 
-import GHC.Show (appPrec)
-
 import Prelude hiding (Show)
 
-import Text.Show.Text.Class (Show(showb, showbPrec), showbParen)
-import Text.Show.Text.Data.Bool (showbBool)
-import Text.Show.Text.Data.Maybe (showbMaybePrec)
-import Text.Show.Text.Utils ((<>), s)
+import Text.Show.Text.Class (Show(showbPrec))
+import Text.Show.Text.Data.Bool ()
+import Text.Show.Text.Data.Maybe ()
+import Text.Show.Text.TH.Internal
 
 -- | Convert an 'All' value to a 'Builder' with the given precedence.
 showbAllPrec :: Int -> All -> Builder
-showbAllPrec p (All a) = showbParen (p > appPrec) $
-        "All {getAll = "
-     <> showbBool a
-     <> s '}'
+showbAllPrec = showbPrec
 {-# INLINE showbAllPrec #-}
 
 -- | Convert an 'Any' value to a 'Builder' with the given precedence.
 showbAnyPrec :: Int -> Any -> Builder
-showbAnyPrec p (Any a) = showbParen (p > appPrec) $
-        "Any {getAny = "
-     <> showbBool a
-     <> s '}'
+showbAnyPrec = showbPrec
 {-# INLINE showbAnyPrec #-}
 
 -- | Convert a 'Dual' value to a 'Builder' with the given precedence.
 showbDualPrec :: Show a => Int -> Dual a -> Builder
-showbDualPrec p (Dual d) = showbParen (p > appPrec) $
-        "Dual {getDual = "
-     <> showb d
-     <> s '}'
+showbDualPrec = showbPrec
 {-# INLINE showbDualPrec #-}
 
 -- | Convert a 'First' value to a 'Builder' with the given precedence.
 showbFirstPrec :: Show a => Int -> First a -> Builder
-showbFirstPrec p (First f) = showbParen (p > appPrec) $
-        "First {getFirst = "
-     <> showbMaybePrec 0 f
-     <> s '}'
+showbFirstPrec = showbPrec
 {-# INLINE showbFirstPrec #-}
 
 -- | Convert a 'Last' value to a 'Builder' with the given precedence.
 showbLastPrec :: Show a => Int -> Last a -> Builder
-showbLastPrec p (Last l) = showbParen (p > appPrec) $
-        "Last {getLast = "
-     <> showbMaybePrec 0 l
-     <> s '}'
+showbLastPrec = showbPrec
 {-# INLINE showbLastPrec #-}
 
 -- | Convert a 'Product' value to a 'Builder' with the given precedence.
 showbProductPrec :: Show a => Int -> Product a -> Builder
-showbProductPrec p (Product prod) = showbParen (p > appPrec) $
-        "Product {getProduct = "
-     <> showb prod
-     <> s '}'
+showbProductPrec = showbPrec
 {-# INLINE showbProductPrec #-}
 
 -- | Convert a 'Sum' value to a 'Builder' with the given precedence.
 showbSumPrec :: Show a => Int -> Sum a -> Builder
-showbSumPrec p (Sum sum') = showbParen (p > appPrec) $
-        "Sum {getSum = "
-     <> showb sum'
-     <> s '}'
+showbSumPrec = showbPrec
 {-# INLINE showbSumPrec #-}
 
-instance Show All where
-    showbPrec = showbAllPrec
-    {-# INLINE showbPrec #-}
-
-instance Show Any where
-    showbPrec = showbAnyPrec
-    {-# INLINE showbPrec #-}
-
-instance Show a => Show (Dual a) where
-    showbPrec = showbDualPrec
-    {-# INLINE showbPrec #-}
-
-instance Show a => Show (First a) where
-    showbPrec = showbFirstPrec
-    {-# INLINE showbPrec #-}
-
-instance Show a => Show (Last a) where
-    showbPrec = showbLastPrec
-    {-# INLINE showbPrec #-}
-
-instance Show a => Show (Product a) where
-    showbPrec = showbProductPrec
-    {-# INLINE showbPrec #-}
-
-instance Show a => Show (Sum a) where
-    showbPrec = showbSumPrec
-    {-# INLINE showbPrec #-}
+$(deriveShow ''All)
+$(deriveShow ''Any)
+$(deriveShow ''Dual)
+$(deriveShow ''First)
+$(deriveShow ''Last)
+$(deriveShow ''Product)
+$(deriveShow ''Sum)
diff --git a/src/Text/Show/Text/Data/Ord.hs b/src/Text/Show/Text/Data/Ord.hs
--- a/src/Text/Show/Text/Data/Ord.hs
+++ b/src/Text/Show/Text/Data/Ord.hs
@@ -1,4 +1,7 @@
-{-# LANGUAGE CPP, NoImplicitPrelude, OverloadedStrings #-}
+{-# LANGUAGE CPP, TemplateHaskell #-}
+#if MIN_VERSION_base(4,6,0)
+{-# LANGUAGE NoImplicitPrelude #-}
+#endif
 {-# OPTIONS_GHC -fno-warn-orphans #-}
 -----------------------------------------------------------------------------
 -- |
@@ -19,34 +22,30 @@
     ) where
 
 import Data.Text.Lazy.Builder (Builder)
-import Prelude hiding (Show)
-import Text.Show.Text.Class (Show(showb))
 
+import Text.Show.Text.Class (showb)
+import Text.Show.Text.TH.Internal (deriveShow)
+
 #if MIN_VERSION_base(4,6,0)
-import Data.Ord (Down(..))
-import GHC.Show (appPrec, appPrec1)
-import Text.Show.Text.Class (showbPrec, showbParen)
-import Text.Show.Text.Utils ((<>))
+import Data.Ord (Down)
+
+import Prelude hiding (Show)
+
+import Text.Show.Text.Class (Show(showbPrec))
 #endif
 
 -- | Convert a 'Ordering' to a 'Builder'.
 showbOrdering :: Ordering -> Builder
-showbOrdering LT = "LT"
-showbOrdering EQ = "EQ"
-showbOrdering GT = "GT"
+showbOrdering = showb
 {-# INLINE showbOrdering #-}
 
-instance Show Ordering where
-    showb = showbOrdering
-    {-# INLINE showb #-}
+$(deriveShow ''Ordering)
 
 #if MIN_VERSION_base(4,6,0)
 -- | Convert a 'Down' value to a 'Builder' with the given precedence.
 showbDownPrec :: Show a => Int -> Down a -> Builder
-showbDownPrec p (Down d) = showbParen (p > appPrec) $ "Down " <> showbPrec appPrec1 d
+showbDownPrec = showbPrec
 {-# INLINE showbDownPrec #-}
 
-instance Show a => Show (Down a) where
-    showbPrec = showbDownPrec
-    {-# INLINE showbPrec #-}
+$(deriveShow ''Down)
 #endif
diff --git a/src/Text/Show/Text/Data/Time.hs b/src/Text/Show/Text/Data/Time.hs
--- a/src/Text/Show/Text/Data/Time.hs
+++ b/src/Text/Show/Text/Data/Time.hs
@@ -1,4 +1,4 @@
-{-# LANGUAGE NoImplicitPrelude, OverloadedStrings #-}
+{-# LANGUAGE CPP, NoImplicitPrelude, OverloadedStrings #-}
 {-# OPTIONS_GHC -fno-warn-orphans #-}
 -----------------------------------------------------------------------------
 -- |
@@ -22,39 +22,71 @@
     , showbTimeZone
     , showbTimeOfDay
     , showbLocalTime
+    , showbZonedTime
     ) where
 
-import Data.Text.Buildable (build)
-import Data.Text.Lazy.Builder (Builder)
-import Data.Time.Calendar (Day)
-import Data.Time.Clock (DiffTime, UTCTime, NominalDiffTime)
-import Data.Time.Clock.TAI (AbsoluteTime, taiToUTCTime)
-import Data.Time.LocalTime (TimeZone, TimeOfDay, LocalTime,
-                            utc, utcToLocalTime)
+import           Data.Text.Lazy.Builder (Builder)
+import           Data.Time.Calendar (Day)
+import           Data.Time.Clock (DiffTime, UTCTime, NominalDiffTime)
+import           Data.Time.Clock.TAI (AbsoluteTime, taiToUTCTime)
+import           Data.Time.LocalTime (TimeZone(..), TimeOfDay(..), LocalTime(..),
+                                      ZonedTime(..), utc, utcToLocalTime)
 
-import Prelude hiding (Show)
+import           Prelude hiding (Show)
 
-import Text.Show.Text.Class (Show(showb))
-import Text.Show.Text.Utils ((<>))
+import           Text.Show.Text.Class (Show(showb))
+import           Text.Show.Text.Utils ((<>))
 
+#if defined(TEXT_FORMAT)
+import           Data.Text.Buildable (build)
+#else
+import           Data.Fixed (Pico)
+import           Data.Text.Lazy.Builder (fromString)
+import           Data.Time.Calendar (toGregorian)
+import           Data.Time.Format (NumericPadOption)
+import           Data.Time.LocalTime (utcToZonedTime)
+
+import qualified Prelude as P
+
+import           Text.Show.Text.Data.Fixed (showbFixed)
+import           Text.Show.Text.Data.Integral ()
+import           Text.Show.Text.Utils (lengthB, replicateB, s)
+#endif
+
 -- | Convert a 'Day' into a 'Builder'.
 showbDay :: Day -> Builder
+#if defined(TEXT_FORMAT)
 showbDay = build
+#else
+showbDay = showbGregorian
+#endif
 {-# INLINE showbDay #-}
 
 -- | Convert a 'DiffTime' into a 'Builder'.
 showbDiffTime :: DiffTime -> Builder
+#if defined(TEXT_FORMAT)
 showbDiffTime = build
+#else
+showbDiffTime = fromString . P.show
+#endif
 {-# INLINE showbDiffTime #-}
 
 -- | Convert a 'UTCTime' into a 'Builder'.
 showbUTCTime :: UTCTime -> Builder
+#if defined(TEXT_FORMAT)
 showbUTCTime = build
+#else
+showbUTCTime = showb . utcToZonedTime utc
+#endif
 {-# INLINE showbUTCTime #-}
 
 -- | Convert a 'NominalDiffTime' into a 'Builder'.
 showbNominalDiffTime :: NominalDiffTime -> Builder
+#if defined(TEXT_FORMAT)
 showbNominalDiffTime = build
+#else
+showbNominalDiffTime = fromString . P.show
+#endif
 {-# INLINE showbNominalDiffTime #-}
 
 -- | Convert a 'AbsoluteTime' into a 'Builder'.
@@ -65,19 +97,105 @@
 
 -- | Convert a 'TimeZone' into a 'Builder'.
 showbTimeZone :: TimeZone -> Builder
+#if defined(TEXT_FORMAT)
 showbTimeZone = build
+#else
+showbTimeZone zone@(TimeZone _ _ "") = timeZoneOffsetBuilder zone
+showbTimeZone (TimeZone _ _ name)    = fromString name
+#endif
 {-# INLINE showbTimeZone #-}
 
 -- | Convert a 'TimeOfDay' into a 'Builder'.
 showbTimeOfDay :: TimeOfDay -> Builder
+#if defined(TEXT_FORMAT)
 showbTimeOfDay = build
+#else
+showbTimeOfDay (TimeOfDay h m sec) = showb2      zeroOpt h
+                                  <> s ':'
+                                  <> showb2      zeroOpt m
+                                  <> s ':'
+                                  <> showb2Fixed zeroOpt sec
+#endif
 {-# INLINE showbTimeOfDay #-}
 
 -- | Convert a 'LocalTime' into a 'Builder'.
 showbLocalTime :: LocalTime -> Builder
+#if defined(TEXT_FORMAT)
 showbLocalTime = build
+#else
+showbLocalTime (LocalTime d t) = showbGregorian d <> s ' ' <> showb t
+#endif
 {-# INLINE showbLocalTime #-}
 
+-- | Convert a 'ZonedTime' into a 'Builder'.
+showbZonedTime :: ZonedTime -> Builder
+#if defined(TEXT_FORMAT)
+showbZonedTime = build
+#else
+showbZonedTime (ZonedTime t zone) = showb t <> s ' ' <> showb zone
+#endif
+{-# INLINE showbZonedTime #-}
+
+#if !defined(TEXT_FORMAT)
+pad1 :: NumericPadOption -> Builder -> Builder
+pad1 (Just c) b = s c <> b
+pad1 _        b = b
+{-# INLINE pad1 #-}
+
+padN :: Int -> Char -> Builder -> Builder
+padN i _ b | i <= 0 = b
+padN i c b          = replicateB (fromIntegral i) (s c) <> b
+{-# INLINE padN #-}
+
+showb2 :: (Num t, Ord t, Show t) => NumericPadOption -> t -> Builder
+showb2 = showbPaddedMin 2
+{-# INLINE showb2 #-}
+
+showb2Fixed :: NumericPadOption -> Pico -> Builder
+showb2Fixed opt x | x < 10 = pad1 opt $ showbFixed True x
+showb2Fixed _   x          = showbFixed True x
+{-# INLINE showb2Fixed #-}
+
+showb4 :: (Num t, Ord t, Show t) => NumericPadOption -> t -> Builder
+showb4 = showbPaddedMin 4
+{-# INLINE showb4 #-}
+
+showbGregorian :: Day -> Builder
+showbGregorian date = showb4 zeroOpt y
+                   <> s '-'
+                   <> showb2 zeroOpt m
+                   <> s '-'
+                   <> showb2 zeroOpt d
+  where
+    (y,m,d) = toGregorian date
+{-# INLINE showbGregorian #-}
+
+showbPaddedMin :: (Num t, Ord t, Show t) => Int -> NumericPadOption -> t -> Builder
+showbPaddedMin _  Nothing  i = showb i
+showbPaddedMin pl opt      i | i < 0 = s '-' <> showbPaddedMin pl opt (negate i)
+showbPaddedMin pl (Just c) i =
+    let b = showb i
+    in padN (pl - fromIntegral (lengthB b)) c b
+{-# INLINE showbPaddedMin #-}
+
+showbT :: NumericPadOption -> Int -> Builder
+showbT opt t = showb4 opt ((div t 60) * 100 + (mod t 60))
+{-# INLINE showbT #-}
+
+timeZoneOffsetBuilder' :: NumericPadOption -> TimeZone -> Builder
+timeZoneOffsetBuilder' opt (TimeZone t _ _) | t < 0 = s '-' <> showbT opt (negate t)
+timeZoneOffsetBuilder' opt (TimeZone t _ _) = s '+' <> showbT opt t
+{-# INLINE timeZoneOffsetBuilder' #-}
+
+timeZoneOffsetBuilder :: TimeZone -> Builder
+timeZoneOffsetBuilder = timeZoneOffsetBuilder' $ Just '0'
+{-# INLINE timeZoneOffsetBuilder #-}
+
+zeroOpt :: NumericPadOption
+zeroOpt = Just '0'
+{-# INLINE zeroOpt #-}
+#endif
+
 instance Show Day where
     showb = showbDay
     {-# INLINE showb #-}
@@ -108,4 +226,8 @@
 
 instance Show LocalTime where
     showb = showbLocalTime
+    {-# INLINE showb #-}
+
+instance Show ZonedTime where
+    showb = showbZonedTime
     {-# INLINE showb #-}
diff --git a/src/Text/Show/Text/Data/Type/Coercion.hs b/src/Text/Show/Text/Data/Type/Coercion.hs
--- a/src/Text/Show/Text/Data/Type/Coercion.hs
+++ b/src/Text/Show/Text/Data/Type/Coercion.hs
@@ -25,6 +25,7 @@
 showbCoercion Coercion = "Coercion"
 {-# INLINE showbCoercion #-}
 
+-- TODO: See why 'deriveShow' doesn't detect that b is a phantom type
 instance Show (Coercion a b) where
     showb = showbCoercion
     {-# INLINE showb #-}
diff --git a/src/Text/Show/Text/Data/Type/Equality.hs b/src/Text/Show/Text/Data/Type/Equality.hs
--- a/src/Text/Show/Text/Data/Type/Equality.hs
+++ b/src/Text/Show/Text/Data/Type/Equality.hs
@@ -25,6 +25,7 @@
 showbPropEquality Refl = "Refl"
 {-# INLINE showbPropEquality #-}
 
+-- TODO: See why 'deriveShow' doesn't detect that b is a phantom type
 instance Show (a :~: b) where
     showb = showbPropEquality
     {-# INLINE showb #-}
diff --git a/src/Text/Show/Text/Data/Typeable.hs b/src/Text/Show/Text/Data/Typeable.hs
--- a/src/Text/Show/Text/Data/Typeable.hs
+++ b/src/Text/Show/Text/Data/Typeable.hs
@@ -17,15 +17,11 @@
 #if MIN_VERSION_base(4,4,0)
     , showbFingerprint
 #endif
-#if MIN_VERSION_base(4,7,0)
     , showbProxy
-#endif
     ) where
 
 import Data.Monoid (mempty)
-#if MIN_VERSION_base(4,7,0)
 import Data.Proxy (Proxy(..))
-#endif
 import Data.Text.Lazy.Builder (Builder, fromString)
 import Data.Typeable (TypeRep, typeRepArgs, typeRepTyCon)
 #if MIN_VERSION_base(4,4,0)
@@ -101,12 +97,10 @@
 showbTyCon = fromString . tyConString
 {-# INLINE showbTyCon #-}
 
-#if MIN_VERSION_base(4,7,0)
 -- | Convert a 'Proxy' type to a 'Builder'.
 showbProxy :: Proxy s -> Builder
 showbProxy _ = "Proxy"
 {-# INLINE showbProxy #-}
-#endif
 
 #if MIN_VERSION_base(4,4,0)
 -- | Convert a 'Fingerprint' to a 'Builder'.
@@ -141,8 +135,7 @@
     {-# INLINE showb #-}
 #endif
 
-#if MIN_VERSION_base(4,7,0)
+-- TODO: See why 'deriveShow' can't detect Proxy's phantom type correctly
 instance Show (Proxy s) where
     showb = showbProxy
     {-# INLINE showb #-}
-#endif
diff --git a/src/Text/Show/Text/Data/Version.hs b/src/Text/Show/Text/Data/Version.hs
--- a/src/Text/Show/Text/Data/Version.hs
+++ b/src/Text/Show/Text/Data/Version.hs
@@ -1,4 +1,4 @@
-{-# LANGUAGE NoImplicitPrelude, OverloadedStrings #-}
+{-# LANGUAGE TemplateHaskell #-}
 {-# OPTIONS_GHC -fno-warn-orphans #-}
 -----------------------------------------------------------------------------
 -- |
@@ -21,24 +21,16 @@
 import Data.Text.Lazy.Builder (Builder, fromString)
 import Data.Version (Version(..))
 
-import GHC.Show (appPrec)
-
-import Prelude hiding (Show)
-
-import Text.Show.Text.Class (Show(showb, showbPrec), showbParen)
+import Text.Show.Text.Class (showb, showbPrec)
 import Text.Show.Text.Data.Char ()
 import Text.Show.Text.Data.Integral ()
 import Text.Show.Text.Data.List ()
+import Text.Show.Text.TH.Internal (deriveShow)
 import Text.Show.Text.Utils ((<>), s)
 
 -- | Convert a 'Version' to a 'Builder' with the given precedence.
 showbVersionPrec :: Int -> Version -> Builder
-showbVersionPrec p (Version b t) = showbParen (p > appPrec) $
-        "Version {versionBranch = "
-     <> showb b
-     <> ", versionTags = "
-     <> showb t
-     <> s '}'
+showbVersionPrec = showbPrec
 {-# INLINE showbVersionPrec #-}
 
 -- | Provides one possible concrete representation for 'Version'.  For
@@ -50,6 +42,4 @@
         mconcat (map ((s '-' <>) . fromString) tags)
 {-# INLINE showbVersionConcrete #-}
 
-instance Show Version where
-    showbPrec = showbVersionPrec
-    {-# INLINE showbPrec #-}
+$(deriveShow ''Version)
diff --git a/src/Text/Show/Text/GHC/Generics.hs b/src/Text/Show/Text/GHC/Generics.hs
--- a/src/Text/Show/Text/GHC/Generics.hs
+++ b/src/Text/Show/Text/GHC/Generics.hs
@@ -1,4 +1,5 @@
-{-# LANGUAGE FlexibleContexts, NoImplicitPrelude, OverloadedStrings, TypeOperators #-}
+{-# LANGUAGE FlexibleContexts, NoImplicitPrelude, OverloadedStrings,
+             TemplateHaskell, TypeOperators #-}
 {-# OPTIONS_GHC -fno-warn-orphans #-}
 -----------------------------------------------------------------------------
 -- |
@@ -27,15 +28,16 @@
 
 import Data.Text.Lazy.Builder (Builder)
 
-import GHC.Generics (U1(..), Par1(..), Rec1(..), K1(..),
+import GHC.Generics (U1(..), Par1, Rec1(..), K1(..),
                      M1(..), (:+:)(..), (:*:)(..), (:.:)(..),
-                     Fixity(..), Associativity(..), Arity(..))
+                     Fixity, Associativity, Arity)
 import GHC.Show (appPrec, appPrec1)
 
 import Prelude hiding (Show)
 
 import Text.Show.Text.Class (Show(showb, showbPrec), showbParen)
-import Text.Show.Text.Data.Integral (showbIntPrec)
+import Text.Show.Text.Data.Integral ()
+import Text.Show.Text.TH.Internal (deriveShow)
 import Text.Show.Text.Utils ((<>), s)
 
 -- | Convert a 'U1' value to a 'Builder'.
@@ -45,8 +47,7 @@
 
 -- | Convert a 'Par1' value to a 'Builder' with the given precedence.
 showbPar1Prec :: Show p => Int -> Par1 p -> Builder
-showbPar1Prec p (Par1 up) = showbParen (p > appPrec) $
-    "Par1 {unPar1 = " <> showb up <> s '}'
+showbPar1Prec = showbPrec
 {-# INLINE showbPar1Prec #-}
 
 -- | Convert a 'Rec1' value to a 'Builder' with the given precedence.
@@ -92,33 +93,26 @@
 
 -- | Convert a 'Fixity' value to a 'Builder' with the given precedence.
 showbFixityPrec :: Int -> Fixity -> Builder
-showbFixityPrec _ Prefix      = "Prefix"
-showbFixityPrec p (Infix a i) = showbParen (p > appPrec) $
-    "Infix " <> showbAssociativity a <> s ' ' <> showbIntPrec appPrec1 i
+showbFixityPrec = showbPrec
 {-# INLINE showbFixityPrec #-}
 
 -- | Convert an 'Associativity' value to a 'Builder'.
 showbAssociativity :: Associativity -> Builder
-showbAssociativity LeftAssociative  = "LeftAssociative"
-showbAssociativity RightAssociative = "RightAssociative"
-showbAssociativity NotAssociative   = "NotAssociative"
+showbAssociativity = showb
 {-# INLINE showbAssociativity #-}
 
 -- | Convert an 'Arity' value to a 'Builder' with the given precedence.
 showbArityPrec :: Int -> Arity -> Builder
-showbArityPrec _ NoArity   = "NoArity"
-showbArityPrec p (Arity i) = showbParen (p > appPrec) $
-    "Arity " <> showbIntPrec appPrec1 i
+showbArityPrec = showbPrec
 {-# INLINE showbArityPrec #-}
 
 instance Show (U1 p) where
     showb = showbU1
     {-# INLINE showb #-}
 
-instance Show p => Show (Par1 p) where
-    showbPrec = showbPar1Prec
-    {-# INLINE showbPrec #-}
+$(deriveShow ''Par1)
 
+-- TODO: 'deriveShow' is not smart enough to derive higher-kinded type contexts
 instance Show (f p) => Show (Rec1 f p) where
     showbPrec = showbRec1Prec
     {-# INLINE showbPrec #-}
@@ -143,14 +137,6 @@
     showbPrec = showbCompFunctorsPrec
     {-# INLINE showbPrec #-}
 
-instance Show Fixity where
-    showbPrec = showbFixityPrec
-    {-# INLINE showbPrec #-}
-
-instance Show Associativity where
-    showb = showbAssociativity
-    {-# INLINE showb #-}
-
-instance Show Arity where
-    showbPrec = showbArityPrec
-    {-# INLINE showbPrec #-}
+$(deriveShow ''Fixity)
+$(deriveShow ''Associativity)
+$(deriveShow ''Arity)
diff --git a/src/Text/Show/Text/GHC/Stats.hs b/src/Text/Show/Text/GHC/Stats.hs
--- a/src/Text/Show/Text/GHC/Stats.hs
+++ b/src/Text/Show/Text/GHC/Stats.hs
@@ -1,4 +1,4 @@
-{-# LANGUAGE CPP, NoImplicitPrelude, OverloadedStrings #-}
+{-# LANGUAGE TemplateHaskell #-}
 {-# OPTIONS_GHC -fno-warn-orphans #-}
 -----------------------------------------------------------------------------
 -- |
@@ -15,63 +15,16 @@
 
 import Data.Text.Lazy.Builder (Builder)
 
-import GHC.Show (appPrec)
-import GHC.Stats (GCStats(..))
-
-import Prelude hiding (Show)
+import GHC.Stats (GCStats)
 
-import Text.Show.Text.Class (Show(showbPrec), showbParen)
-import Text.Show.Text.Data.Integral (showbInt64Prec)
-import Text.Show.Text.Data.Floating (showbDoublePrec)
-import Text.Show.Text.Utils ((<>), s)
+import Text.Show.Text.Class (showbPrec)
+import Text.Show.Text.Data.Integral ()
+import Text.Show.Text.Data.Floating ()
+import Text.Show.Text.TH.Internal (deriveShow)
 
 -- | Convert a 'GCStats' value to a 'Builder' with the given precedence.
 showbGCStatsPrec :: Int -> GCStats -> Builder
-showbGCStatsPrec p gcStats = showbParen (p > appPrec) $
-       "GCStats {bytesAllocated = "
-    <> showbInt64Prec 0 (bytesAllocated gcStats)
-    <> ", numGcs = "
-    <> showbInt64Prec 0 (numGcs gcStats)
-    <> ", maxBytesUsed = "
-    <> showbInt64Prec 0 (maxBytesUsed gcStats)
-    <> ", numByteUsageSamples = "
-    <> showbInt64Prec 0 (numByteUsageSamples gcStats)
-    <> ", cumulativeBytesUsed = "
-    <> showbInt64Prec 0 (cumulativeBytesUsed gcStats)
-    <> ", bytesCopied = "
-    <> showbInt64Prec 0 (bytesCopied gcStats)
-    <> ", currentBytesUsed = "
-    <> showbInt64Prec 0 (currentBytesUsed gcStats)
-    <> ", currentBytesSlop = "
-    <> showbInt64Prec 0 (currentBytesSlop gcStats)
-    <> ", maxBytesSlop = "
-    <> showbInt64Prec 0 (maxBytesSlop gcStats)
-    <> ", peakMegabytesAllocated = "
-    <> showbInt64Prec 0 (peakMegabytesAllocated gcStats)
-    <> ", mutatorCpuSeconds = "
-    <> showbDoublePrec 0 (mutatorCpuSeconds gcStats)
-    <> ", mutatorWallSeconds = "
-    <> showbDoublePrec 0 (mutatorWallSeconds gcStats)
-    <> ", gcCpuSeconds = "
-    <> showbDoublePrec 0 (gcCpuSeconds gcStats)
-    <> ", gcWallSeconds = "
-    <> showbDoublePrec 0 (gcWallSeconds gcStats)
-    <> ", cpuSeconds = "
-    <> showbDoublePrec 0 (cpuSeconds gcStats)
-    <> ", wallSeconds = "
-    <> showbDoublePrec 0 (wallSeconds gcStats)
-#if MIN_VERSION_base(4,6,0)
-    <> ", parTotBytesCopied = "
-    <> showbInt64Prec 0 (parTotBytesCopied gcStats)
-#else
-    <> ", parAvgBytesCopied = "
-    <> showbInt64Prec 0 (parAvgBytesCopied gcStats)
-#endif
-    <> ", parMaxBytesCopied = "
-    <> showbInt64Prec 0 (parMaxBytesCopied gcStats)
-    <> s '}'
+showbGCStatsPrec = showbPrec
 {-# INLINE showbGCStatsPrec #-}
 
-instance Show GCStats where
-    showbPrec = showbGCStatsPrec
-    {-# INLINE showbPrec #-}
+$(deriveShow ''GCStats)
diff --git a/src/Text/Show/Text/System/Exit.hs b/src/Text/Show/Text/System/Exit.hs
--- a/src/Text/Show/Text/System/Exit.hs
+++ b/src/Text/Show/Text/System/Exit.hs
@@ -1,4 +1,4 @@
-{-# LANGUAGE NoImplicitPrelude, OverloadedStrings #-}
+{-# LANGUAGE TemplateHaskell #-}
 {-# OPTIONS_GHC -fno-warn-orphans #-}
 -----------------------------------------------------------------------------
 -- |
@@ -15,23 +15,15 @@
 
 import Data.Text.Lazy.Builder (Builder)
 
-import GHC.Show (appPrec, appPrec1)
-
-import Prelude hiding (Show)
-
-import System.Exit (ExitCode(..))
+import System.Exit (ExitCode)
 
-import Text.Show.Text.Class (Show(showbPrec), showbParen)
-import Text.Show.Text.Data.Integral (showbIntPrec)
-import Text.Show.Text.Utils ((<>))
+import Text.Show.Text.Class (showbPrec)
+import Text.Show.Text.Data.Integral ()
+import Text.Show.Text.TH.Internal (deriveShow)
 
 -- | Convert an 'ExitCode' to a 'Builder' with the given precedence.
 showbExitCodePrec :: Int -> ExitCode -> Builder
-showbExitCodePrec _ ExitSuccess     = "ExitSuccess"
-showbExitCodePrec p (ExitFailure c) = showbParen (p > appPrec) $
-    "ExitFailure " <> showbIntPrec appPrec1 c
+showbExitCodePrec = showbPrec
 {-# INLINE showbExitCodePrec #-}
 
-instance Show ExitCode where
-    showbPrec = showbExitCodePrec
-    {-# INLINE showbPrec #-}
+$(deriveShow ''ExitCode)
diff --git a/src/Text/Show/Text/System/IO.hs b/src/Text/Show/Text/System/IO.hs
--- a/src/Text/Show/Text/System/IO.hs
+++ b/src/Text/Show/Text/System/IO.hs
@@ -1,4 +1,4 @@
-{-# LANGUAGE CPP, NoImplicitPrelude, OverloadedStrings #-}
+{-# LANGUAGE CPP, NoImplicitPrelude, OverloadedStrings, TemplateHaskell #-}
 {-# OPTIONS_GHC -fno-warn-orphans #-}
 -----------------------------------------------------------------------------
 -- |
@@ -31,24 +31,23 @@
 import Data.Text.Lazy.Builder (Builder, fromString)
 
 #if MIN_VERSION_base(4,3,0)
-import GHC.IO.Encoding.Types (TextEncoding(..))
+import GHC.IO.Encoding.Types (TextEncoding(textEncodingName))
 #endif
 #if MIN_VERSION_base(4,4,0)
-import GHC.IO.Encoding.Failure (CodingFailureMode(..))
-import GHC.IO.Encoding.Types (CodingProgress(..))
+import GHC.IO.Encoding.Failure (CodingFailureMode)
+import GHC.IO.Encoding.Types (CodingProgress)
 #endif
 import GHC.IO.Handle (HandlePosn(..))
 import GHC.IO.Handle.Types (Handle(..))
-import GHC.Show (appPrec, appPrec1)
 
 import Prelude hiding (Show)
 
-import System.IO (BufferMode(..), IOMode(..), Newline(..),
-                  NewlineMode(..), SeekMode(..))
+import System.IO (BufferMode, IOMode, Newline, NewlineMode, SeekMode)
 
-import Text.Show.Text.Class (Show(showb, showbPrec), showbParen)
+import Text.Show.Text.Class (Show(showb, showbPrec))
 import Text.Show.Text.Data.Integral (showbIntegerPrec)
-import Text.Show.Text.Data.Maybe (showbMaybePrec)
+import Text.Show.Text.Data.Maybe ()
+import Text.Show.Text.TH.Internal (deriveShow)
 import Text.Show.Text.Utils ((<>), s)
 
 -- | Convert a 'Handle' to a 'Builder'.
@@ -64,18 +63,12 @@
 
 -- | Convert an 'IOMode' to a 'Builder'.
 showbIOMode :: IOMode -> Builder
-showbIOMode ReadMode      = "ReadMode"
-showbIOMode WriteMode     = "WriteMode"
-showbIOMode AppendMode    = "AppendMode"
-showbIOMode ReadWriteMode = "ReadWriteMode"
+showbIOMode = showb
 {-# INLINE showbIOMode #-}
 
 -- | Convert a 'BufferMode' to a 'Builder' with the given precedence.
 showbBufferModePrec :: Int -> BufferMode -> Builder
-showbBufferModePrec _ NoBuffering   = "NoBuffering"
-showbBufferModePrec _ LineBuffering = "LineBuffering"
-showbBufferModePrec p (BlockBuffering size)
-    = showbParen (p > appPrec) $ "BlockBuffering " <> showbMaybePrec appPrec1 size
+showbBufferModePrec = showbPrec
 {-# INLINE showbBufferModePrec #-}
 
 -- | Convert a 'HandlePosn' to a 'Builder'.
@@ -86,9 +79,7 @@
 
 -- | Convert a 'SeekMode' to a 'Builder'.
 showbSeekMode :: SeekMode -> Builder
-showbSeekMode AbsoluteSeek = "AbsoluteSeek"
-showbSeekMode RelativeSeek = "RelativeSeek"
-showbSeekMode SeekFromEnd  = "SeekFromEnd"
+showbSeekMode = showb
 {-# INLINE showbSeekMode #-}
 
 #if MIN_VERSION_base(4,3,0)
@@ -101,55 +92,37 @@
 #if MIN_VERSION_base(4,4,0)
 -- | Convert a 'CodingProgress' to a 'Builder'.
 showbCodingProgress :: CodingProgress -> Builder
-showbCodingProgress InputUnderflow  = "InputUnderflow"
-showbCodingProgress OutputUnderflow = "OutputUnderflow"
-showbCodingProgress InvalidSequence = "InvalidSequence"
+showbCodingProgress = showb
 {-# INLINE showbCodingProgress #-}
 
 -- | Convert a 'CodingFailureMode' value to a 'Builder'.
 showbCodingFailureMode :: CodingFailureMode -> Builder
-showbCodingFailureMode ErrorOnCodingFailure       = "ErrorOnCodingFailure"
-showbCodingFailureMode IgnoreCodingFailure        = "IgnoreCodingFailure"
-showbCodingFailureMode TransliterateCodingFailure = "TransliterateCodingFailure"
-showbCodingFailureMode RoundtripFailure           = "RoundtripFailure"
+showbCodingFailureMode = showb
 {-# INLINE showbCodingFailureMode #-}
 #endif
 
 -- | Convert a 'Newline' to a 'Builder'.
 showbNewline :: Newline -> Builder
-showbNewline LF   = "LF"
-showbNewline CRLF = "CRLF"
+showbNewline = showb
 {-# INLINE showbNewline #-}
 
 -- | Convert a 'NewlineMode' to a 'Builder' with the given precedence.
 showbNewlineModePrec :: Int -> NewlineMode -> Builder
-showbNewlineModePrec p (NewlineMode inl onl) = showbParen (p > appPrec) $
-       "NewlineMode {inputNL = "
-    <> showbNewline inl
-    <> ", outputNL = "
-    <> showbNewline onl
-    <> s '}'
+showbNewlineModePrec = showbPrec
 {-# INLINE showbNewlineModePrec #-}
 
 instance Show Handle where
     showb = showbHandle
     {-# INLINE showb #-}
 
-instance Show IOMode where
-    showb = showbIOMode
-    {-# INLINE showb #-}
-
-instance Show BufferMode where
-    showbPrec = showbBufferModePrec
-    {-# INLINE showbPrec #-}
+$(deriveShow ''IOMode)
+$(deriveShow ''BufferMode)
 
 instance Show HandlePosn where
     showb = showbHandlePosn
     {-# INLINE showb #-}
 
-instance Show SeekMode where
-    showb = showbSeekMode
-    {-# INLINE showb #-}
+$(deriveShow ''SeekMode)
 
 #if MIN_VERSION_base(4,3,0)
 instance Show TextEncoding where
@@ -158,19 +131,9 @@
 #endif
 
 #if MIN_VERSION_base(4,4,0)
-instance Show CodingProgress where
-    showb = showbCodingProgress
-    {-# INLINE showb #-}
-
-instance Show CodingFailureMode where
-    showb = showbCodingFailureMode
-    {-# INLINE showb #-}
+$(deriveShow ''CodingProgress)
+$(deriveShow ''CodingFailureMode)
 #endif
 
-instance Show Newline where
-    showb = showbNewline
-    {-# INLINE showb #-}
-
-instance Show NewlineMode where
-    showbPrec = showbNewlineModePrec
-    {-# INLINE showbPrec #-}
+$(deriveShow ''Newline)
+$(deriveShow ''NewlineMode)
diff --git a/src/Text/Show/Text/TH/Internal.hs b/src/Text/Show/Text/TH/Internal.hs
--- a/src/Text/Show/Text/TH/Internal.hs
+++ b/src/Text/Show/Text/TH/Internal.hs
@@ -77,7 +77,9 @@
 
 Note that at the moment, 'deriveShow' does not support data families,
 so it is impossible to use 'deriveShow' with @data instance@s or @newtype
-instance@s.
+instance@s. Also, 'deriveShow' lacks the ability to properly detect data types
+with higher-kinded type parameters (e.g., @data HK f a = HK (f a)@), so it cannot
+create instances for them either.
 
 -}
 
diff --git a/tests/Instances/BaseAndFriends.hs b/tests/Instances/BaseAndFriends.hs
--- a/tests/Instances/BaseAndFriends.hs
+++ b/tests/Instances/BaseAndFriends.hs
@@ -39,9 +39,7 @@
 #if MIN_VERSION_base(4,6,0)
 import           Data.Ord (Down(..))
 #endif
-#if MIN_VERSION_base(4,7,0)
 import           Data.Proxy (Proxy(..))
-#endif
 import           Data.Text.Lazy.Builder (Builder, fromString)
 #if MIN_VERSION_base(4,7,0)
 import           Data.Coerce (Coercible)
@@ -228,10 +226,8 @@
 -- instance Arbitrary Number
 -- #endif
 
-#if MIN_VERSION_base(4,7,0)
 instance Arbitrary (Proxy s) where
     arbitrary = pure Proxy
-#endif
 
 #if MIN_VERSION_base(4,4,0)
 -- TODO: Come up with an instance of TypeRep that doesn't take forever
diff --git a/tests/Properties/BaseAndFriends.hs b/tests/Properties/BaseAndFriends.hs
--- a/tests/Properties/BaseAndFriends.hs
+++ b/tests/Properties/BaseAndFriends.hs
@@ -41,9 +41,7 @@
 #if MIN_VERSION_base(4,6,0)
 import           Data.Ord (Down(..))
 #endif
-#if MIN_VERSION_base(4,7,0)
 import           Data.Proxy (Proxy)
-#endif
 import           Data.Ratio (Ratio)
 import           Data.Sequence (Seq)
 import           Data.Set (Set)
@@ -52,7 +50,7 @@
 import           Data.Time.Calendar (Day)
 import           Data.Time.Clock (DiffTime, UTCTime, NominalDiffTime)
 import           Data.Time.Clock.TAI (AbsoluteTime)
-import           Data.Time.LocalTime (TimeZone, TimeOfDay, LocalTime)
+import           Data.Time.LocalTime (TimeZone, TimeOfDay, LocalTime, ZonedTime)
 import           Data.Tree (Tree)
 #if MIN_VERSION_base(4,7,0)
 import           Data.Type.Coercion (Coercion)
@@ -168,6 +166,7 @@
         , testProperty "RecSelError instance"               (prop_matchesShow :: Int -> RecSelError -> Bool)
         , testProperty "RecUpdError instance"               (prop_matchesShow :: Int -> RecUpdError -> Bool)
         , testProperty "ErrorCall instance"                 (prop_matchesShow :: Int -> ErrorCall -> Bool)
+        , testProperty "MaskingState instance"              (prop_matchesShow :: Int -> MaskingState -> Bool)
         ]
     , testGroup "Text.Show.Text.Control.Monad.ST"
         [ testProperty "ST instance"                        (prop_matchesShow :: Int -> ST Int Int -> Bool)
@@ -288,6 +287,7 @@
         , testProperty "TimeZone instance"                  (prop_matchesShow :: Int -> TimeZone -> Bool)
         , testProperty "TimeOfDay instance"                 (prop_matchesShow :: Int -> TimeOfDay -> Bool)
         , testProperty "LocalTime instance"                 (prop_matchesShow :: Int -> LocalTime -> Bool)
+        , testProperty "ZonedTime instance"                 (prop_matchesShow :: Int -> ZonedTime -> Bool)
         ]
     , testGroup "Text.Show.Text.Data.Tuple"
         [ testProperty "() instance"                        (prop_matchesShow :: Int -> () -> Bool)
@@ -309,11 +309,9 @@
         [ -- testProperty "TypeRep instance"                   (prop_matchesShow :: Int -> TypeRep -> Bool)
           testProperty "TyCon instance"                     (prop_matchesShow :: Int -> TyCon -> Bool)
         , testProperty "Fingerprint instance"               (prop_matchesShow :: Int -> Fingerprint -> Bool)
-#if MIN_VERSION_base(4,7,0)
-        , testProperty "Proxy Int instance"                 (prop_matchesShow :: Int -> Proxy Int -> Bool)
 #endif
+        , testProperty "Proxy Int instance"                 (prop_matchesShow :: Int -> Proxy Int -> Bool)
         ]
-#endif
     , testGroup "Text.Show.Text.Data.Version"
         [ testProperty "Version instance"                   (prop_matchesShow :: Int -> Version -> Bool)
         , testProperty "showbVersionConcrete output"        prop_showVersion
diff --git a/tests/Properties/Derived.hs b/tests/Properties/Derived.hs
--- a/tests/Properties/Derived.hs
+++ b/tests/Properties/Derived.hs
@@ -59,8 +59,9 @@
         , testProperty "PolymorphicInfix Int Int Int instance"       (prop_matchesShow :: Int -> PolymorphicInfix Int Int Int -> Bool)
         , testProperty "AllAtOnce Int Int Int Int instance"          (prop_matchesShow :: Int -> AllAtOnce Int Int Int Int -> Bool)
         , testProperty "GADT instance"                               prop_showGADT
-        , testProperty "LeftAssocTree Int instance"                  (prop_matchesShow :: Int -> LeftAssocTree Int -> Bool)
-        , testProperty "RightAssocTree Int instance"                 (prop_matchesShow :: Int -> RightAssocTree Int -> Bool)
+-- TODO: These tests take forever. Look at quickcheck-instances (specifically, at the Tree instance) to see how to fix this.
+--         , testProperty "LeftAssocTree Int instance"                  (prop_matchesShow :: Int -> LeftAssocTree Int -> Bool)
+--         , testProperty "RightAssocTree Int instance"                 (prop_matchesShow :: Int -> RightAssocTree Int -> Bool)
         , testProperty "Int :?: Int instance"                        (prop_matchesShow :: Int -> Int :?: Int -> Bool)
         ]
     ]
diff --git a/text-show.cabal b/text-show.cabal
--- a/text-show.cabal
+++ b/text-show.cabal
@@ -1,5 +1,5 @@
 name:                text-show
-version:             0.3.1.0
+version:             0.4
 synopsis:            Efficient conversion of values into Text
 description:         @text-show@ offers a replacement for the @Show@ typeclass intended
                      for use with @Text@ instead of @String@s. This package was created
@@ -58,6 +58,14 @@
   type:                git
   location:            git://github.com/RyanGlScott/text-show.git
 
+flag text-format
+  description:         Do not use text-format, since it may require double-conversion
+                       and thus linking of libstdc++, which may break compilation
+                       due to GHC bug #5289:
+                       .
+                       http://ghc.haskell.org/trac/ghc/ticket/5289
+  default:             False
+
 library
   exposed-modules:     Text.Show.Text
                        Text.Show.Text.TH
@@ -103,18 +111,24 @@
                        Text.Show.Text.Text
                        Text.Show.Text.TH.Internal
                        Text.Show.Text.Utils
-  build-depends:       array            >= 0.3 && < 0.6
-                     , base             >= 4.2 && < 5
-                     , bytestring       >= 0.9 && < 0.11
-                     , containers       >= 0.1 && < 0.6
+  build-depends:       array            >= 0.3   && < 0.6
+                     , base             >= 4.2   && < 5
+                     , bytestring       >= 0.9   && < 0.11
+                     , containers       >= 0.1   && < 0.6
                      , ghc-prim
-                     , template-haskell >= 2.4 && < 2.10
-                     , text             >= 0.2 && < 1.3
-                     , text-format      >= 0.2 && < 0.4
-                     , time             >= 0.1 && < 1.6
+                     , template-haskell >= 2.4   && < 2.10
+                     , text             >= 0.2   && < 1.3
+                     , time             >= 0.1   && < 1.6
   hs-source-dirs:      src
   ghc-options:         -Wall
   
+  if flag(text-format)
+    cpp-options:       -DTEXT_FORMAT
+    build-depends:     text-format      >= 0.2   && < 0.4
+  else  
+    build-depends: integer-gmp >= 0.2
+    ghc-options:   -fobject-code
+  
   if impl(ghc >= 7.2)
     exposed-modules:   Text.Show.Text.GHC.Event
                        Text.Show.Text.GHC.Generics
@@ -122,6 +136,10 @@
   if impl(ghc >= 7.4)
     exposed-modules:   Text.Show.Text.GHC.Stats
   
+  -- Data.Proxy is a part of base as of GHC 7.7
+  if impl(ghc < 7.7)
+    build-depends:     tagged           >= 0.4.4 && < 1
+  
   if impl(ghc >= 7.8)
     exposed-modules:   Text.Show.Text.Data.Type.Coercion
                        Text.Show.Text.Data.Type.Equality
@@ -136,19 +154,23 @@
                        Properties.MkShow
                        Properties.Utils
   hs-source-dirs:      tests
-  build-depends:       array                      >= 0.3 && < 0.6
-                     , base                       >= 4.2 && < 5
-                     , bytestring                 >= 0.9 && < 0.11
-                     , containers                 >= 0.1 && < 0.6
-                     , QuickCheck                 >= 2.4 && < 2.8
-                     , quickcheck-instances       >= 0.1 && < 0.4
-                     , tasty                      >= 0.8 && < 0.11
-                     , tasty-quickcheck           >= 0.8 && < 0.9
-                     , text                       >= 0.2 && < 1.3
-                     , text-show                  >= 0.3 && < 0.4
-                     , time                       >= 0.1 && < 1.6
+  build-depends:       array                      >= 0.3   && < 0.6
+                     , base                       >= 4.2   && < 5
+                     , bytestring                 >= 0.9   && < 0.11
+                     , containers                 >= 0.1   && < 0.6
+                     , QuickCheck                 >= 2.4   && < 2.8
+                     , quickcheck-instances       >= 0.1   && < 0.4
+                     , tasty                      >= 0.8   && < 0.11
+                     , tasty-quickcheck           >= 0.8   && < 0.9
+                     , text                       >= 0.2   && < 1.3
+                     , text-show                  >= 0.4   && < 0.5
+                     , time                       >= 0.1   && < 1.6
   ghc-options:         -Wall
   
   -- Prior to GHC 7.6, GHC generics lived in ghc-prim
   if impl(ghc >= 7.2) && impl(ghc < 7.6)
     build-depends:     ghc-prim
+
+  -- Data.Proxy is a part of base as of GHC 7.7
+  if impl(ghc < 7.7)
+    build-depends:     tagged                     >= 0.4.4 && < 1
