diff --git a/ChangeLog.md b/ChangeLog.md
new file mode 100644
--- /dev/null
+++ b/ChangeLog.md
@@ -0,0 +1,8 @@
+# Revision history for dependent-sum
+
+## 0.5.0.0
+
+* Make `Some` a `newtype` with associated pattern synonyms using `unsafeCoerce`
+  to avoid the GADT performance overhead. This shouldn't affect users.
+* Deprecate the constructor name `This` in favor of `Some`.
+* Drop support for GHC older than 8.0.
diff --git a/dependent-sum.cabal b/dependent-sum.cabal
--- a/dependent-sum.cabal
+++ b/dependent-sum.cabal
@@ -1,5 +1,5 @@
 name:                   dependent-sum
-version:                0.4
+version:                0.5
 stability:              provisional
 
 cabal-version:          >= 1.6
@@ -24,15 +24,12 @@
                         dependent sum types by using your own \"tag\"
                         types.
 
-tested-with:            GHC == 7.0.4,
-                        GHC == 7.2.2,
-                        GHC == 7.4.2,
-                        GHC == 7.6.3,
-                        GHC == 7.8.4,
-                        GHC == 7.10.1,
-                        GHC == 7.11
+tested-with:            GHC == 8.0.2,
+                        GHC == 8.2.2,
+                        GHC == 8.4.4
 
 extra-source-files:     examples/*.hs
+                        ChangeLog.md
 
 source-repository head
   type:     git
diff --git a/src/Data/GADT/Compare.hs b/src/Data/GADT/Compare.hs
--- a/src/Data/GADT/Compare.hs
+++ b/src/Data/GADT/Compare.hs
@@ -22,6 +22,11 @@
 import Data.GADT.Show
 import Data.Typeable
 
+#if MIN_VERSION_base(4,10,0)
+import qualified Type.Reflection as TR
+import Data.Type.Equality (testEquality)
+#endif
+
 #if MIN_VERSION_base(4,7,0)
 -- |Backwards compatibility alias; as of GHC 7.8, this is the same as `(:~:)`.
 type (:=) = (:~:)
@@ -93,6 +98,11 @@
 instance GEq ((:=) a) where
     geq (Refl :: a := b) (Refl :: a := c) = Just (Refl :: b := c)
 
+#if MIN_VERSION_base(4,10,0)
+instance GEq TR.TypeRep where
+    geq = testEquality
+#endif
+
 -- This instance seems nice, but it's simply not right:
 -- 
 -- > instance GEq StableName where
@@ -166,6 +176,20 @@
 
 instance GCompare ((:=) a) where
     gcompare Refl Refl = GEQ
+
+#if MIN_VERSION_base(4,10,0)
+instance GCompare TR.TypeRep where
+    gcompare t1 t2 =
+      case testEquality t1 t2 of
+        Just Refl -> GEQ
+        Nothing ->
+          case compare (TR.SomeTypeRep t1) (TR.SomeTypeRep t2) of
+            LT -> GLT
+            GT -> GGT
+            EQ -> error "impossible: 'testEquality' and 'compare' \
+                        \are inconsistent for TypeRep; report this \
+                        \as a GHC bug"
+#endif
 
 defaultCompare :: GCompare f => f a -> f b -> Ordering
 defaultCompare x y = weakenOrdering (gcompare x y)
diff --git a/src/Data/GADT/Show.hs b/src/Data/GADT/Show.hs
--- a/src/Data/GADT/Show.hs
+++ b/src/Data/GADT/Show.hs
@@ -8,6 +8,10 @@
 #endif
 module Data.GADT.Show where
 
+#if MIN_VERSION_base(4,10,0)
+import qualified Type.Reflection as TR
+#endif
+
 -- |'Show'-like class for 1-type-parameter GADTs.  @GShow t => ...@ is equivalent to something
 -- like @(forall a. Show (t a)) => ...@.  The easiest way to create instances would probably be
 -- to write (or derive) an @instance Show (T a)@, and then simply say:
@@ -16,6 +20,11 @@
 class GShow t where
     gshowsPrec :: Int -> t a -> ShowS
 
+
+#if MIN_VERSION_base(4,10,0)
+instance GShow TR.TypeRep where
+    gshowsPrec = showsPrec
+#endif
 
 gshows :: GShow t => t a -> ShowS
 gshows = gshowsPrec (-1)
diff --git a/src/Data/Some.hs b/src/Data/Some.hs
--- a/src/Data/Some.hs
+++ b/src/Data/Some.hs
@@ -1,40 +1,52 @@
-{-# LANGUAGE GADTs #-}
-{-# LANGUAGE RankNTypes #-}
 {-# LANGUAGE CPP #-}
-#if defined(__GLASGOW_HASKELL__) && __GLASGOW_HASKELL__ >= 702
-{-# LANGUAGE Safe #-}
-#endif
-#if defined(__GLASGOW_HASKELL__) && __GLASGOW_HASKELL__ >= 708
+{-# LANGUAGE GADTs #-}
+{-# LANGUAGE PatternSynonyms #-}
 {-# LANGUAGE PolyKinds #-}
-#endif
-module Data.Some where
+{-# LANGUAGE RankNTypes #-}
+{-# LANGUAGE Trustworthy #-}
+{-# LANGUAGE ViewPatterns #-}
+module Data.Some (Some(Some, This), withSome) where
 
 import Data.GADT.Show
 import Data.GADT.Compare
-import Data.Maybe
+import GHC.Exts (Any)
+import Unsafe.Coerce
 
-data Some tag where
-    This :: !(tag t) -> Some tag
+newtype Some tag = UnsafeSome (tag Any)
 
+#if __GLASGOW_HASKELL__ >= 801
+{-# COMPLETE Some #-}
+#endif
+pattern Some :: tag a -> Some tag
+pattern Some x <- UnsafeSome ((unsafeCoerce :: tag Any -> tag a) -> x)
+  where Some x = UnsafeSome ((unsafeCoerce :: tag a -> tag Any) x)
+
+#if __GLASGOW_HASKELL__ >= 801
+{-# COMPLETE This #-}
+#endif
+{-# DEPRECATED This "Use 'Some' instead" #-}
+pattern This :: tag a -> Some tag
+pattern This x = Some x
+
 withSome :: Some tag -> (forall a. tag a -> b) -> b
-withSome (This thing) some = some thing
+withSome (Some thing) some = some thing
 
 instance GShow tag => Show (Some tag) where
-    showsPrec p (This thing) = showParen (p > 10)
-        ( showString "This "
+    showsPrec p (Some thing) = showParen (p > 10)
+        ( showString "Some "
         . gshowsPrec 11 thing
         )
 
 instance GRead f => Read (Some f) where
     readsPrec p = readParen (p>10) $ \s ->
-        [ (getGReadResult withTag This, rest')
+        [ (getGReadResult withTag Some, rest')
         | let (con, rest) = splitAt 5 s
-        , con == "This "
+        , con == "Some "
         , (withTag, rest') <- greadsPrec 11 rest
         ]
 
 instance GEq tag => Eq (Some tag) where
-    This x == This y = defaultEq x y
+    Some x == Some y = defaultEq x y
 
 instance GCompare tag => Ord (Some tag) where
-    compare (This x) (This y) = defaultCompare x y
+    compare (Some x) (Some y) = defaultCompare x y
