diff --git a/README.md b/README.md
--- a/README.md
+++ b/README.md
@@ -12,3 +12,4 @@
 * [fisx](http://github.com/fisx)
 * [Timo von Holtz](http://github.com/tvh)
 * [Brendan Hay](http://github.com/brendanhay)
+* [k0ral](https://github.com/k0ral)
diff --git a/bench/Main.hs b/bench/Main.hs
--- a/bench/Main.hs
+++ b/bench/Main.hs
@@ -1,11 +1,13 @@
+{-# LANGUAGE FlexibleInstances #-}
+{-# LANGUAGE GADTs             #-}
 {-# LANGUAGE OverloadedStrings #-}
 {-# OPTIONS_GHC -fno-warn-orphans #-}
 module Main (main) where
 
 -------------------------------------------------------------------------------
-import           Control.DeepSeq.Generics
-import           Criterion.Main
 import           Blaze.ByteString.Builder
+import           Control.DeepSeq
+import           Criterion.Main
 import           Data.String
 import qualified Network.URI              as NU
 -------------------------------------------------------------------------------
@@ -16,15 +18,17 @@
 instance NFData Authority
 instance NFData Host
 instance NFData UserInfo
-instance NFData URI
-instance NFData RelativeRef
 instance NFData SchemaError
 instance NFData URIParseError
 instance NFData Scheme
 instance NFData Port
 instance NFData Query
 
+instance NFData (URIRef a) where
+  rnf (URI a b c d e) = rnf a `seq` rnf b `seq` rnf c `seq` rnf d `seq` rnf e
+  rnf (RelativeRef b c d e) = rnf b `seq` rnf c `seq` rnf d `seq` rnf e
 
+
 -------------------------------------------------------------------------------
 main :: IO ()
 main = defaultMain
@@ -39,8 +43,8 @@
       ]
   , bgroup "serializing"
     [
-      bench "URI.ByteString.serializeURI" $ nf (toLazyByteString . serializeURI) exampleURI
-    , bench "URI.ByteString.serializeRelativeRef" $ nf (toLazyByteString . serializeRelativeRef) exampleRelativeRef
+      bench "URI.ByteString.serializeURIRef on URI" $ nf (toLazyByteString . serializeURIRef) exampleURI
+    , bench "URI.ByteString.serializeURIRef on relative ref" $ nf (toLazyByteString . serializeURIRef) exampleRelativeRef
     ]
   ]
 
diff --git a/src/URI/ByteString.hs b/src/URI/ByteString.hs
--- a/src/URI/ByteString.hs
+++ b/src/URI/ByteString.hs
@@ -31,23 +31,24 @@
     , Authority(..)
     , UserInfo(..)
     , Query(..)
-    , URI(..)
-    , RelativeRef(..)
+    , URIRef(..)
+    , Absolute
+    , Relative
     , SchemaError(..)
     , URIParseError(..)
     , URIParserOptions(..)
     , strictURIParserOptions
     , laxURIParserOptions
+    -- * Operations
+    , toAbsolute
     -- * Parsing
     , parseURI
     , parseRelativeRef
     , uriParser
     , relativeRefParser
     -- * Serializing
-    , serializeURI
-    , serializeURI'
-    , serializeRelativeRef
-    , serializeRelativeRef'
+    , serializeURIRef
+    , serializeURIRef'
     -- * Low level utility functions
     , urlDecode
     , urlDecodeQuery
@@ -70,19 +71,29 @@
     , uiPasswordL
     -- ** Lenses over 'Query'
     , queryPairsL
-    -- ** Lenses over 'URI'
+    -- ** Lenses over 'URIRef'
     , uriSchemeL
+    , authorityL
+    , pathL
+    , queryL
+    , fragmentL
+    -- ** Lenses over 'URIParserOptions'
+    , upoValidQueryCharL
+    -- ** Deprecated
+    , URI
+    , RelativeRef
+    , serializeURI
+    , serializeURI'
+    , serializeRelativeRef
+    , serializeRelativeRef'
     , uriAuthorityL
     , uriPathL
     , uriQueryL
     , uriFragmentL
-    -- ** Lenses over 'RelativeRef'
     , rrAuthorityL
     , rrPathL
     , rrQueryL
     , rrFragmentL
-    -- ** Lenses over 'URIParserOptions'
-    , upoValidQueryCharL
     ) where
 
 -------------------------------------------------------------------------------
diff --git a/src/URI/ByteString/Internal.hs b/src/URI/ByteString/Internal.hs
--- a/src/URI/ByteString/Internal.hs
+++ b/src/URI/ByteString/Internal.hs
@@ -1,3 +1,4 @@
+{-# LANGUAGE GADTs                      #-}
 {-# LANGUAGE GeneralizedNewtypeDeriving #-}
 {-# LANGUAGE OverloadedStrings          #-}
 {-# LANGUAGE RecordWildCards            #-}
@@ -48,29 +49,47 @@
       upoValidQueryChar = validForQueryLax
     }
 
+
 -------------------------------------------------------------------------------
+-- | @toAbsolute scheme ref@ converts @ref@ to an absolute URI.
+-- If @ref@ is already absolute, then it is unchanged.
+toAbsolute :: Scheme -> URIRef a -> URIRef Absolute
+toAbsolute scheme (RelativeRef {..}) = URI scheme rrAuthority rrPath rrQuery rrFragment
+toAbsolute _ uri@(URI {..}) = uri
+
+-------------------------------------------------------------------------------
 -- | URI Serializer
 -------------------------------------------------------------------------------
 
--- | Serialize a URI into a Builder.
+-- | Serialize a URI reference into a 'Builder'.
 --
 -- Example of serializing + converting to a lazy "Data.ByteString.Lazy.ByteString":
 --
--- >>> BB.toLazyByteString $ serializeURI $ URI {uriScheme = Scheme {schemeBS = "http"}, uriAuthority = Just (Authority {authorityUserInfo = Nothing, authorityHost = Host {hostBS = "www.example.org"}, authorityPort = Nothing}), uriPath = "/foo", uriQuery = Query {queryPairs = [("bar","baz")]}, uriFragment = Just "quux"}
+-- >>> BB.toLazyByteString $ serializeURIRef $ URI {uriScheme = Scheme {schemeBS = "http"}, uriAuthority = Just (Authority {authorityUserInfo = Nothing, authorityHost = Host {hostBS = "www.example.org"}, authorityPort = Nothing}), uriPath = "/foo", uriQuery = Query {queryPairs = [("bar","baz")]}, uriFragment = Just "quux"}
 -- "http://www.example.org/foo?bar=baz#quux"
-serializeURI :: URI -> Builder
-serializeURI URI {..} = scheme <> BB.fromString ":" <>
-                        serializeRelativeRef rr
+serializeURIRef :: URIRef a -> Builder
+serializeURIRef uri@(URI {..}) = serializeURI uri
+serializeURIRef uri@(RelativeRef {..}) = serializeRelativeRef uri
+
+-- | Like 'serializeURIRef', with conversion into a strict 'ByteString'.
+serializeURIRef' :: URIRef a -> ByteString
+serializeURIRef' = BB.toByteString . serializeURIRef
+
+-- | Serialize a URI into a Builder.
+serializeURI :: URIRef Absolute -> Builder
+serializeURI URI {..} = scheme <> BB.fromString ":" <> serializeRelativeRef rr
   where
     scheme = bs $ schemeBS uriScheme
     rr = RelativeRef uriAuthority uriPath uriQuery uriFragment
+{-# DEPRECATED serializeURI "Use 'serializeURIRef' instead" #-}
 
 -- | Like 'serializeURI', with conversion into a strict 'ByteString'.
-serializeURI' :: URI -> ByteString
+serializeURI' :: URIRef Absolute -> ByteString
 serializeURI' = BB.toByteString . serializeURI
+{-# DEPRECATED serializeURI' "Use 'serializeURIRef'' instead" #-}
 
 -- | Like 'serializeURI', but do not render scheme.
-serializeRelativeRef :: RelativeRef -> Builder
+serializeRelativeRef :: URIRef Relative -> Builder
 serializeRelativeRef RelativeRef {..} = authority <> path <> query <> fragment
   where
     path = mconcat $ intersperse (c8 '/') $ map urlEncodePath segs
@@ -78,10 +97,12 @@
     authority = maybe mempty serializeAuthority rrAuthority
     query = serializeQuery rrQuery
     fragment = maybe mempty (\s -> c8 '#' <> bs s) rrFragment
+{-# DEPRECATED serializeRelativeRef "Use 'serializeURIRef' instead" #-}
 
 -- | Like 'serializeRelativeRef', with conversion into a strict 'ByteString'.
-serializeRelativeRef' :: RelativeRef -> ByteString
+serializeRelativeRef' :: URIRef Relative -> ByteString
 serializeRelativeRef' = BB.toByteString . serializeRelativeRef
+{-# DEPRECATED serializeRelativeRef' "Use 'serializeURIRef'' instead" #-}
 
 -------------------------------------------------------------------------------
 serializeQuery :: Query -> Builder
@@ -141,11 +162,11 @@
 -- >>> let myLaxOptions = URIParserOptions { upoValidQueryChar = liftA2 (||) (upoValidQueryChar strictURIParserOptions) (inClass "[]")}
 -- >>> parseURI myLaxOptions "http://www.example.org/foo?bar[]=baz"
 -- Right (URI {uriScheme = Scheme {schemeBS = "http"}, uriAuthority = Just (Authority {authorityUserInfo = Nothing, authorityHost = Host {hostBS = "www.example.org"}, authorityPort = Nothing}), uriPath = "/foo", uriQuery = Query {queryPairs = [("bar[]","baz")]}, uriFragment = Nothing})
-parseURI :: URIParserOptions -> ByteString -> Either URIParseError URI
+parseURI :: URIParserOptions -> ByteString -> Either URIParseError (URIRef Absolute)
 parseURI opts = parseOnly' OtherError (uriParser' opts)
 
 -- | Like 'parseURI', but do not parse scheme.
-parseRelativeRef :: URIParserOptions -> ByteString -> Either URIParseError RelativeRef
+parseRelativeRef :: URIParserOptions -> ByteString -> Either URIParseError (URIRef Relative)
 parseRelativeRef opts = parseOnly' OtherError (relativeRefParser' opts)
 
 
@@ -156,13 +177,13 @@
 
 -------------------------------------------------------------------------------
 -- | Underlying attoparsec parser. Useful for composing with your own parsers.
-uriParser :: URIParserOptions -> Parser URI
+uriParser :: URIParserOptions -> Parser (URIRef Absolute)
 uriParser = unParser' . uriParser'
 
 
 -------------------------------------------------------------------------------
 -- | Toplevel parser for URIs
-uriParser' :: URIParserOptions -> URIParser URI
+uriParser' :: URIParserOptions -> URIParser (URIRef Absolute)
 uriParser' opts = do
   scheme <- schemeParser
   void $ word8 colon `orFailWith` MalformedScheme MissingColon
@@ -172,13 +193,13 @@
 
 -------------------------------------------------------------------------------
 -- | Underlying attoparsec parser. Useful for composing with your own parsers.
-relativeRefParser :: URIParserOptions -> Parser RelativeRef
+relativeRefParser :: URIParserOptions -> Parser (URIRef Relative)
 relativeRefParser = unParser' . relativeRefParser'
 
 
 -------------------------------------------------------------------------------
 -- | Toplevel parser for relative refs
-relativeRefParser' :: URIParserOptions -> URIParser RelativeRef
+relativeRefParser' :: URIParserOptions -> URIParser (URIRef Relative)
 relativeRefParser' opts = do
   (authority, path) <- hierPartParser <|> rrPathParser
   query <- queryParser opts
diff --git a/src/URI/ByteString/Lens.hs b/src/URI/ByteString/Lens.hs
--- a/src/URI/ByteString/Lens.hs
+++ b/src/URI/ByteString/Lens.hs
@@ -1,4 +1,6 @@
-{-# LANGUAGE RankNTypes #-}
+{-# LANGUAGE GADTs           #-}
+{-# LANGUAGE RankNTypes      #-}
+{-# LANGUAGE RecordWildCards #-}
 module URI.ByteString.Lens where
 
 
@@ -84,17 +86,11 @@
 
 
 -------------------------------------------------------------------------------
-uriSchemeL :: Lens' URI Scheme
-uriSchemeL =
-  lens uriScheme (\a b -> a { uriScheme = b})
-{-# INLINE uriSchemeL #-}
-
-
--------------------------------------------------------------------------------
 uriAuthorityL :: Lens' URI (Maybe Authority)
 uriAuthorityL =
   lens uriAuthority (\a b -> a { uriAuthority = b})
 {-# INLINE uriAuthorityL #-}
+{-# DEPRECATED uriAuthorityL "Use 'authorityL' instead" #-}
 
 
 -------------------------------------------------------------------------------
@@ -102,6 +98,7 @@
 uriPathL =
   lens uriPath (\a b -> a { uriPath = b})
 {-# INLINE uriPathL #-}
+{-# DEPRECATED uriPathL "Use 'pathL' instead" #-}
 
 
 -------------------------------------------------------------------------------
@@ -109,6 +106,7 @@
 uriQueryL =
   lens uriQuery (\a b -> a { uriQuery = b})
 {-# INLINE uriQueryL #-}
+{-# DEPRECATED uriQueryL "Use 'queryL' instead" #-}
 
 
 -------------------------------------------------------------------------------
@@ -116,6 +114,7 @@
 uriFragmentL =
   lens uriFragment (\a b -> a { uriFragment = b})
 {-# INLINE uriFragmentL #-}
+{-# DEPRECATED uriFragmentL "Use 'fragmentL' instead" #-}
 
 
 -------------------------------------------------------------------------------
@@ -123,6 +122,7 @@
 rrAuthorityL =
   lens rrAuthority (\a b -> a { rrAuthority = b})
 {-# INLINE rrAuthorityL #-}
+{-# DEPRECATED rrAuthorityL "Use 'authorityL' instead" #-}
 
 
 -------------------------------------------------------------------------------
@@ -130,6 +130,7 @@
 rrPathL =
   lens rrPath (\a b -> a { rrPath = b})
 {-# INLINE rrPathL #-}
+{-# DEPRECATED rrPathL "Use 'pathL' instead" #-}
 
 
 -------------------------------------------------------------------------------
@@ -137,6 +138,7 @@
 rrQueryL =
   lens rrQuery (\a b -> a { rrQuery = b})
 {-# INLINE rrQueryL #-}
+{-# DEPRECATED rrQueryL "Use 'queryL' instead" #-}
 
 
 -------------------------------------------------------------------------------
@@ -144,6 +146,63 @@
 rrFragmentL =
   lens rrFragment (\a b -> a { rrFragment = b})
 {-# INLINE rrFragmentL #-}
+{-# DEPRECATED rrFragmentL "Use 'fragmentL' instead" #-}
+
+
+-------------------------------------------------------------------------------
+uriSchemeL :: Lens' (URIRef Absolute) Scheme
+uriSchemeL = lens uriScheme setter where
+  setter :: URIRef Absolute  -> Scheme -> URIRef Absolute
+  setter (URI _ b c d e) a' = URI a' b c d e
+{-# INLINE uriSchemeL #-}
+
+
+-------------------------------------------------------------------------------
+authorityL :: Lens' (URIRef a) (Maybe Authority)
+authorityL = lens getter setter where
+  getter :: URIRef a -> Maybe Authority
+  getter (URI {..}) = uriAuthority
+  getter (RelativeRef {..}) = rrAuthority
+  setter :: URIRef a -> Maybe Authority -> URIRef a
+  setter (URI a _ c d e) b' = URI a b' c d e
+  setter (RelativeRef _ c d e) b' = RelativeRef b' c d e
+{-# INLINE authorityL #-}
+
+
+-------------------------------------------------------------------------------
+pathL :: Lens' (URIRef a) ByteString
+pathL = lens getter setter where
+  getter :: URIRef a -> ByteString
+  getter (URI {..}) = uriPath
+  getter (RelativeRef {..}) = rrPath
+  setter :: URIRef a -> ByteString -> URIRef a
+  setter (URI a b _ d e) c' = URI a b c' d e
+  setter (RelativeRef b _ d e) c' = RelativeRef b c' d e
+{-# INLINE pathL #-}
+
+
+-------------------------------------------------------------------------------
+queryL :: Lens' (URIRef a) Query
+queryL = lens getter setter where
+  getter :: URIRef a -> Query
+  getter (URI {..}) = uriQuery
+  getter (RelativeRef {..}) = rrQuery
+  setter :: URIRef a -> Query -> URIRef a
+  setter (URI a b c _ e) d' = URI a b c d' e
+  setter (RelativeRef b c _ e) d' = RelativeRef b c d' e
+{-# INLINE queryL #-}
+
+
+-------------------------------------------------------------------------------
+fragmentL :: Lens' (URIRef a) (Maybe ByteString)
+fragmentL = lens getter setter where
+  getter :: URIRef a -> Maybe ByteString
+  getter (URI {..}) = uriFragment
+  getter (RelativeRef {..}) = rrFragment
+  setter :: URIRef a -> Maybe ByteString -> URIRef a
+  setter (URI a b c d _) e' = URI a b c d e'
+  setter (RelativeRef b c d _) e' = RelativeRef b c d e'
+{-# INLINE fragmentL #-}
 
 
 -------------------------------------------------------------------------------
diff --git a/src/URI/ByteString/Types.hs b/src/URI/ByteString/Types.hs
--- a/src/URI/ByteString/Types.hs
+++ b/src/URI/ByteString/Types.hs
@@ -1,6 +1,9 @@
+{-# LANGUAGE CPP                        #-}
 {-# LANGUAGE DeriveDataTypeable         #-}
 {-# LANGUAGE DeriveGeneric              #-}
+{-# LANGUAGE GADTs                      #-}
 {-# LANGUAGE GeneralizedNewtypeDeriving #-}
+{-# LANGUAGE StandaloneDeriving         #-}
 module URI.ByteString.Types where
 
 -------------------------------------------------------------------------------
@@ -53,24 +56,43 @@
 
 
 -------------------------------------------------------------------------------
-data URI = URI {
-      uriScheme    :: Scheme
-    , uriAuthority :: Maybe Authority
-    , uriPath      :: ByteString
-    , uriQuery     :: Query
-    , uriFragment  :: Maybe ByteString
-    -- ^ URI fragment. Does not include the #
-    } deriving (Show, Eq, Generic, Typeable, Ord)
+-- | Note: URI fragment does not include the #
+data URIRef a where
+  URI :: { uriScheme :: Scheme
+         , uriAuthority :: Maybe Authority
+         , uriPath :: ByteString
+         , uriQuery :: Query
+         , uriFragment :: Maybe ByteString
+         } -> URIRef Absolute
+  RelativeRef :: { rrAuthority :: Maybe Authority
+                 , rrPath :: ByteString
+                 , rrQuery :: Query
+                 , rrFragment :: Maybe ByteString
+                 } -> URIRef Relative
 
+deriving instance Show (URIRef a)
+deriving instance Eq (URIRef a)
+-- deriving instance Generic (URIRef a)
+deriving instance Ord (URIRef a)
 
+#ifdef WITH_TYPEABLE
+deriving instance Typeable URIRef
+#endif
+
 -------------------------------------------------------------------------------
-data RelativeRef = RelativeRef {
-      rrAuthority :: Maybe Authority
-    , rrPath      :: ByteString
-    , rrQuery     :: Query
-    , rrFragment  :: Maybe ByteString
-    -- ^ URI fragment. Does not include the #
-    } deriving (Show, Eq, Generic, Typeable, Ord)
+data Absolute deriving(Typeable)
+
+
+-------------------------------------------------------------------------------
+data Relative deriving(Typeable)
+
+
+-------------------------------------------------------------------------------
+type URI = URIRef Absolute
+
+
+-------------------------------------------------------------------------------
+type RelativeRef = URIRef Relative
 
 
 -------------------------------------------------------------------------------
diff --git a/test/URI/ByteString/Arbitrary.hs b/test/URI/ByteString/Arbitrary.hs
--- a/test/URI/ByteString/Arbitrary.hs
+++ b/test/URI/ByteString/Arbitrary.hs
@@ -1,4 +1,5 @@
-{-# LANGUAGE TemplateHaskell #-}
+{-# LANGUAGE FlexibleInstances #-}
+{-# LANGUAGE TemplateHaskell   #-}
 {-# OPTIONS_GHC -fno-warn-orphans #-}
 module URI.ByteString.Arbitrary where
 
@@ -35,7 +36,7 @@
   arbitrary = Port <$> arbitrary
 
 
-instance Arbitrary URI where
+instance Arbitrary (URIRef Absolute) where
   arbitrary = URI <$> arbitrary
                   <*> arbitrary
                   <*> arbitrary
@@ -43,7 +44,7 @@
                   <*> arbitrary
 
 
-instance Arbitrary RelativeRef where
+instance Arbitrary (URIRef Relative) where
   arbitrary = RelativeRef <$> arbitrary
                           <*> arbitrary
                           <*> arbitrary
diff --git a/test/URI/ByteStringTests.hs b/test/URI/ByteStringTests.hs
--- a/test/URI/ByteStringTests.hs
+++ b/test/URI/ByteStringTests.hs
@@ -1,13 +1,14 @@
+{-# LANGUAGE GADTs               #-}
 {-# LANGUAGE OverloadedStrings   #-}
 {-# LANGUAGE ScopedTypeVariables #-}
 module URI.ByteStringTests (tests) where
 
 -------------------------------------------------------------------------------
-import           Control.Lens
 import qualified Blaze.ByteString.Builder as BB
 import           Data.ByteString          (ByteString)
 import qualified Data.ByteString.Char8    as B8
 import           Data.Monoid
+import           Lens.Simple
 import           Test.Tasty
 import           Test.Tasty.HUnit
 import           Test.Tasty.QuickCheck
@@ -206,31 +207,31 @@
   , testProperty "uriSchemeL Lens" $ \uri x ->
      (uri ^. uriSchemeL === uriScheme uri) .&&.
      ((uri & uriSchemeL .~ x) === uri { uriScheme = x })
-  , testProperty "uriAuthorityL Lens" $ \uri x ->
-     (uri ^. uriAuthorityL === uriAuthority uri) .&&.
-     ((uri & uriAuthorityL .~ x) === uri { uriAuthority = x })
-  , testProperty "uriPathL Lens" $ \uri x ->
-     (uri ^. uriPathL === uriPath uri) .&&.
-     ((uri & uriPathL .~ x) === uri { uriPath = x })
-  , testProperty "uriQueryL Lens" $ \uri x ->
-     (uri ^. uriQueryL === uriQuery uri) .&&.
-     ((uri & uriQueryL .~ x) === uri { uriQuery = x })
-  , testProperty "uriFragmentL Lens" $ \uri x ->
-     (uri ^. uriFragmentL === uriFragment uri) .&&.
-     ((uri & uriFragmentL .~ x) === uri { uriFragment = x })
+  , testProperty "authorityL Lens on URI" $ \uri x ->
+     (uri ^. authorityL === uriAuthority uri) .&&.
+     ((uri & authorityL .~ x) === uri { uriAuthority = x })
+  , testProperty "pathL Lens on URI" $ \uri x ->
+     (uri ^. pathL === uriPath uri) .&&.
+     ((uri & pathL .~ x) === uri { uriPath = x })
+  , testProperty "queryL Lens on URI" $ \uri x ->
+     (uri ^. queryL === uriQuery uri) .&&.
+     ((uri & queryL .~ x) === uri { uriQuery = x })
+  , testProperty "fragmentL Lens on URI" $ \uri x ->
+     (uri ^. fragmentL === uriFragment uri) .&&.
+     ((uri & fragmentL .~ x) === uri { uriFragment = x })
 
-  , testProperty "rrAuthorityL Lens" $ \rr x ->
-     (rr ^. rrAuthorityL === rrAuthority rr) .&&.
-     ((rr & rrAuthorityL .~ x) === rr { rrAuthority = x })
-  , testProperty "rrPathL Lens" $ \rr x ->
-     (rr ^. rrPathL === rrPath rr) .&&.
-     ((rr & rrPathL .~ x) === rr { rrPath = x })
-  , testProperty "rrQueryL Lens" $ \rr x ->
-     (rr ^. rrQueryL === rrQuery rr) .&&.
-     ((rr & rrQueryL .~ x) === rr { rrQuery = x })
-  , testProperty "rrFragmentL Lens" $ \rr x ->
-     (rr ^. rrFragmentL === rrFragment rr) .&&.
-     ((rr & rrFragmentL .~ x) === rr { rrFragment = x })
+  , testProperty "authorityL Lens on relative ref" $ \rr x ->
+     (rr ^. authorityL === rrAuthority rr) .&&.
+     ((rr & authorityL .~ x) === rr { rrAuthority = x })
+  , testProperty "pathL Lens on relative ref" $ \rr x ->
+     (rr ^. pathL === rrPath rr) .&&.
+     ((rr & pathL .~ x) === rr { rrPath = x })
+  , testProperty "queryL Lens on relative ref" $ \rr x ->
+     (rr ^. queryL === rrQuery rr) .&&.
+     ((rr & queryL .~ x) === rr { rrQuery = x })
+  , testProperty "fragmentL Lens on relative ref" $ \rr x ->
+     (rr ^. fragmentL === rrFragment rr) .&&.
+     ((rr & fragmentL .~ x) === rr { rrFragment = x })
   ]
 
 
@@ -296,7 +297,7 @@
     -> ByteString
     -> TestTree
 roundtripTestURI opts s =
-    testCase (B8.unpack s) $ (parseURI opts s >>= return . BB.toByteString . serializeURI) @?= Right s
+    testCase (B8.unpack s) $ (parseURI opts s >>= return . serializeURIRef') @?= Right s
 
 
 -------------------------------------------------------------------------------
@@ -311,7 +312,7 @@
 
 -------------------------------------------------------------------------------
 serializeURITests :: TestTree
-serializeURITests = testGroup "serializeURI"
+serializeURITests = testGroup "serializeURIRef"
   [
     testCase "renders userinfo correctly" $ do
        let ui = UserInfo "user" "pass"
@@ -320,7 +321,7 @@
                  "/"
                  (Query [("foo", "bar")])
                  (Just "somefragment")
-       let res = BB.toLazyByteString (serializeURI uri)
+       let res = BB.toLazyByteString (serializeURIRef uri)
        res @?= "http://user:pass@www.example.org/?foo=bar#somefragment"
   , testCase "encodes decoded paths" $ do
        let uri = URI (Scheme "http")
@@ -328,6 +329,6 @@
                  "/weird path"
                  (Query [])
                  Nothing
-       let res = BB.toLazyByteString (serializeURI uri)
+       let res = BB.toLazyByteString (serializeURIRef uri)
        res @?= "http://www.example.org/weird%20path"
   ]
diff --git a/uri-bytestring.cabal b/uri-bytestring.cabal
--- a/uri-bytestring.cabal
+++ b/uri-bytestring.cabal
@@ -1,5 +1,5 @@
 name:                uri-bytestring
-version:             0.1.9.2
+version:             0.2.0.0
 synopsis:            Haskell URI parsing as ByteStrings
 description: uri-bytestring aims to be an RFC3986 compliant URI parser that uses efficient ByteStrings for parsing and representing the URI data.
 license:             BSD3
@@ -44,6 +44,9 @@
   hs-source-dirs:      src
   default-language:    Haskell2010
 
+  if impl(ghc >= 7.8)
+    cpp-options: -DWITH_TYPEABLE
+
   if flag(lib-Werror)
     ghc-options: -Werror
 
@@ -68,7 +71,7 @@
     , base
     , blaze-builder
     , bytestring
-    , lens
+    , lens-simple
     , quickcheck-instances
     , semigroups
   default-language:    Haskell2010
