diff --git a/CHANGELOG.markdown b/CHANGELOG.markdown
--- a/CHANGELOG.markdown
+++ b/CHANGELOG.markdown
@@ -1,3 +1,8 @@
+0.8
+---
+* Added `Data.Proxy.TH`, based on the code from `Frames` by Anthony Cowley.
+* Removed `reproxy` from `Data.Proxy`. This is a bad API decision, but it isn't present in GHC's `Data.Proxy`, and this makes the API more stable.
+
 0.7.3
 ---
 * Support `Data.Bifunctor` in `base` for GHC 7.9+.
diff --git a/old/Data/Proxy.hs b/old/Data/Proxy.hs
--- a/old/Data/Proxy.hs
+++ b/old/Data/Proxy.hs
@@ -27,7 +27,6 @@
     (
     -- * Proxy values
       Proxy(..)
-    , reproxy
     , asProxyTypeOf
     ) where
 
@@ -163,18 +162,6 @@
     {-# INLINE mapM #-}
     sequence _ = return Proxy
     {-# INLINE sequence #-}
-
--- | Some times you need to change the proxy you have lying around.
--- Idiomatic usage is to make a new combinator for the relationship
--- between the proxies that you want to enforce, and define that
--- combinator using 'reproxy'.
---
--- > data Succ n
--- > reproxySucc :: proxy n -> Proxy (Succ n)
--- > reproxySucc = reproxy
-reproxy :: proxy s -> Proxy t
-reproxy _ = Proxy
-{-# INLINE reproxy #-}
 
 -- | 'asProxyTypeOf' is a type-restricted version of 'const'.
 -- It is usually used as an infix operator, and its typing forces its first
diff --git a/src/Data/Proxy/TH.hs b/src/Data/Proxy/TH.hs
new file mode 100644
--- /dev/null
+++ b/src/Data/Proxy/TH.hs
@@ -0,0 +1,93 @@
+{-# LANGUAGE CPP #-}
+module Data.Proxy.TH
+  ( pr
+#if __GLASGOW_HASKELL__ >= 704
+  , pr1
+#endif
+  ) where
+
+import Data.Char
+#if __GLASGOW_HASKELL__ < 710
+import Data.Functor
+#endif
+#if __GLASGOW_HASKELL__ < 707
+import Data.Version (showVersion)
+import Paths_tagged
+#endif
+import Language.Haskell.TH
+import Language.Haskell.TH.Quote
+import Language.Haskell.TH.Syntax
+
+proxy_d, proxy_tc :: Name
+#if __GLASGOW_HASKELL__ >= 707
+proxy_d  = mkNameG_d "base" "Data.Proxy" "Proxy"
+proxy_tc = mkNameG_tc "base" "Data.Proxy" "Proxy"
+#else
+proxy_d  = mkNameG_d taggedPackageKey "Data.Proxy" "Proxy"
+proxy_tc = mkNameG_tc taggedPackageKey "Data.Proxy" "Proxy"
+
+-- note: On 7.10+ this would use CURRENT_PACKAGE_KEY if we still housed the key.
+taggedPackageKey :: String
+taggedPackageKey = "tagged-" ++ showVersion version
+#endif
+
+proxyTypeQ :: TypeQ -> TypeQ
+proxyTypeQ t = appT (conT proxy_tc) t
+
+proxyExpQ :: TypeQ -> ExpQ
+proxyExpQ t = sigE (conE proxy_d) (proxyTypeQ t)
+
+proxyPatQ :: TypeQ -> PatQ
+proxyPatQ t = sigP (conP proxy_d []) (proxyTypeQ t)
+
+-- | A proxy value quasiquoter. @[pr|T|]@ will splice an expression
+-- @Proxy::Proxy T@, while @[pr|A,B,C|]@ will splice in a value of
+-- @Proxy :: Proxy [A,B,C]@.
+
+-- TODO: parse a richer syntax for the types involved here so we can include spaces, applications, etc.
+pr :: QuasiQuoter
+pr = QuasiQuoter (mkProxy proxyExpQ) (mkProxy proxyPatQ) (mkProxy proxyTypeQ) undefined where
+  mkProxy :: (TypeQ -> r) -> String -> r
+  mkProxy p s = case ts of
+    [h@(t:_)]
+       | isUpper t -> p $ head <$> cons
+       | otherwise -> p $ varT $ mkName h
+#if __GLASGOW_HASKELL__ >= 704
+    _ -> p $ mkList <$> cons
+#endif
+    where 
+      ts = map strip $ splitOn ',' s
+      cons = mapM (conT . mkName) ts
+#if __GLASGOW_HASKELL__ >= 704
+      mkList = foldr (AppT . AppT PromotedConsT) PromotedNilT
+#endif
+
+#if __GLASGOW_HASKELL__ >= 704
+-- | Like 'pr', but takes a single type, which is used to produce a
+-- 'Proxy' for a single-element list containing only that type. This
+-- is useful for passing a single type to a function that wants a list
+-- of types.
+
+-- TODO: parse a richer syntax for the types involved here so we can include spaces, applications, etc.
+pr1 :: QuasiQuoter
+pr1 = QuasiQuoter (mkProxy proxyExpQ) (mkProxy proxyPatQ) (mkProxy proxyTypeQ) undefined where
+  sing x = AppT (AppT PromotedConsT x) PromotedNilT
+  mkProxy p s = case s of
+    t:_ 
+      | isUpper t -> p (fmap sing (conT $ mkName s))
+      | otherwise -> p (fmap sing (varT $ mkName s))
+    _ -> error "Empty string passed to pr1"
+#endif
+
+-- | Split on a delimiter.
+splitOn :: Eq a => a -> [a] -> [[a]]
+splitOn d = go where
+  go [] = []
+  go xs = case t of
+      [] -> [h]
+      (_:t') -> h : go t' 
+    where (h,t) = break (== d) xs
+
+-- | Remove white space from both ends of a 'String'.
+strip :: String -> String
+strip = takeWhile (not . isSpace) . dropWhile isSpace
diff --git a/src/Data/Tagged.hs b/src/Data/Tagged.hs
--- a/src/Data/Tagged.hs
+++ b/src/Data/Tagged.hs
@@ -11,7 +11,7 @@
 ----------------------------------------------------------------------------
 -- |
 -- Module     : Data.Tagged
--- Copyright  : 2009-2013 Edward Kmett
+-- Copyright  : 2009-2015 Edward Kmett
 -- License    : BSD3
 --
 -- Maintainer  : Edward Kmett <ekmett@gmail.com>
@@ -34,6 +34,8 @@
     , proxy
     , unproxy
     , tagWith
+    -- * Proxy methods GHC dropped
+    , reproxy
     ) where
 
 import Control.Applicative ((<$>), liftA2, Applicative(..))
@@ -296,3 +298,16 @@
 tagWith :: proxy s -> a -> Tagged s a
 tagWith _ = Tagged
 {-# INLINE tagWith #-}
+
+-- | Some times you need to change the proxy you have lying around.
+-- Idiomatic usage is to make a new combinator for the relationship
+-- between the proxies that you want to enforce, and define that
+-- combinator using 'reproxy'.
+--
+-- @
+-- data Succ n
+-- reproxySucc :: proxy n -> 'Proxy' (Succ n)
+-- reproxySucc = 'reproxy'
+-- @
+reproxy :: proxy a -> Proxy b
+reproxy _ = Proxy
diff --git a/tagged.cabal b/tagged.cabal
--- a/tagged.cabal
+++ b/tagged.cabal
@@ -1,5 +1,5 @@
 name:           tagged
-version:        0.7.3
+version:        0.8
 license:        BSD3
 license-file:   LICENSE
 author:         Edward A. Kmett
@@ -31,6 +31,11 @@
     cpp-options: -DLANGUAGE_DeriveDataTypeable
     other-extensions: DeriveDataTypeable
 
-  if !impl(ghc>=7.7)
+  if impl(ghc<7.7)
     hs-source-dirs: old
     exposed-modules: Data.Proxy
+    other-modules: Paths_tagged
+
+  if impl(ghc)
+    exposed-modules: Data.Proxy.TH
+    build-depends: template-haskell >= 2.5 && < 2.11
