diff --git a/CHANGELOG.md b/CHANGELOG.md
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,6 +1,11 @@
 Changelog
 =========
 
+3.4.0
+------
+- Removed `ParseV` and surrounding machinery.
+  Use `versioning` now instead of the `parseV` function.
+
 3.3.2
 ------
 - GHC 8.4.1 compatibility.
diff --git a/Data/Versions.hs b/Data/Versions.hs
--- a/Data/Versions.hs
+++ b/Data/Versions.hs
@@ -29,7 +29,7 @@
 -- incrementing and has the best constraints on comparisons.
 --
 -- == Using the Parsers
--- In general, `parseV` is the function you want. It attempts to parse
+-- In general, `versioning` is the function you want. It attempts to parse
 -- a given @Text@ using the three individual parsers, `semver`, `version`
 -- and `mess`. If one fails, it tries the next. If you know you only want
 -- to parse one specific version type, use that parser directly
@@ -45,14 +45,12 @@
     , VUnit(..), digits, str
     , VChunk
     , VSep(..)
-      -- * Parsers
-    , VParser(..), ParsingError
-    , semver, version, mess
-      -- ** Wrapped Parsers
-    , parseV, semverP, versionP, messP
+      -- * Parsing Versions
+    , ParsingError
+    , versioning, semver, version, mess
       -- ** Megaparsec Parsers
       -- | For when you'd like to mix version parsing into some larger parser.
-    , semver', version', mess'
+    , versioning', semver', version', mess'
       -- * Pretty Printing
     , prettyV, prettySemVer, prettyVer, prettyMess, parseErrorPretty
       -- * Lenses
@@ -163,7 +161,7 @@
 -- "1.2.4"
 -- @
 _Versioning :: Traversal' T.Text Versioning
-_Versioning f t = either (const (pure t)) (fmap prettyV . f) $ parseV t
+_Versioning f t = either (const (pure t)) (fmap prettyV . f) $ versioning t
 {-# INLINE _Versioning #-}
 
 -- | Traverse some Text for its inner SemVer.
@@ -536,38 +534,20 @@
 -- | A synonym for the more verbose `megaparsec` error type.
 type ParsingError = ParseError (Token T.Text) Void
 
--- | A wrapper for a parser function. Can be composed via their
--- Monoid instance, such that a different parser can be tried
--- if a previous one fails.
-newtype VParser = VParser { runVP :: T.Text -> Either ParsingError Versioning }
-
-instance Semigroup VParser where
-  -- | Will attempt the right parser if the left one fails.
-  (VParser f) <> (VParser g) = VParser h
-    where h t = either (const (g t)) Right $ f t
-
-instance Monoid VParser where
-  -- | A parser which will always fail.
-  mempty = VParser $ \_ -> Ideal <$> semver ""
-
-#if __GLASGOW_HASKELL__ < 841
-  mappend = (<>)
-#endif
-
 -- | Parse a piece of `T.Text` into either an (Ideal) `SemVer`, a (General)
 -- `Version`, or a (Complex) `Mess`.
-parseV :: T.Text -> Either ParsingError Versioning
-parseV = runVP $ semverP <> versionP <> messP
+versioning :: T.Text -> Either ParsingError Versioning
+versioning = parse versioning' "versioning"
 
--- | A wrapped `SemVer` parser. Can be composed with other parsers.
-semverP :: VParser
-semverP = VParser $ fmap Ideal . semver
+-- | Parse a `Versioning`. Assumes that the version number is the last token in the string.
+versioning' :: Parsec Void T.Text Versioning
+versioning' = try (fmap Ideal semver' <* eof) <|> try (fmap General version' <* eof) <|> (fmap Complex mess' <* eof)
 
 -- | Parse a (Ideal) Semantic Version.
 semver :: T.Text -> Either ParsingError SemVer
 semver = parse (semver' <* eof) "Semantic Version"
 
--- | Internal megaparsec parser of 'semverP'.
+-- | Internal megaparsec parser of `semver`.
 semver' :: Parsec Void T.Text SemVer
 semver' = SemVer <$> majorP <*> minorP <*> patchP <*> preRel <*> metaData
 
@@ -610,30 +590,22 @@
 sunit :: Parsec Void T.Text VUnit
 sunit = Str . T.pack <$> some letterChar
 
--- | A wrapped `Version` parser. Can be composed with other parsers.
-versionP :: VParser
-versionP = VParser $ fmap General . version
-
 -- | Parse a (General) `Version`, as defined above.
 version :: T.Text -> Either ParsingError Version
 version = parse (version' <* eof) "Version"
 
--- | Internal megaparsec parser of 'versionP'.
+-- | Internal megaparsec parser of `version`.
 version' :: Parsec Void T.Text Version
 version' = Version <$> optional (try epochP) <*> chunks <*> preRel
 
 epochP :: Parsec Void T.Text Word
 epochP = read <$> (some digitChar <* char ':')
 
--- | A wrapped `Mess` parser. Can be composed with other parsers.
-messP :: VParser
-messP = VParser $ fmap Complex . mess
-
 -- | Parse a (Complex) `Mess`, as defined above.
 mess :: T.Text -> Either ParsingError Mess
 mess = parse (mess' <* eof) "Mess"
 
--- | Internal megaparsec parser of 'messP'.
+-- | Internal megaparsec parser of `mess`.
 mess' :: Parsec Void T.Text Mess
 mess' = try node <|> leaf
 
diff --git a/README.md b/README.md
--- a/README.md
+++ b/README.md
@@ -1,7 +1,6 @@
 versions
 ========
 
-[![Build Status](https://travis-ci.org/fosskers/versions.svg?branch=master)](https://travis-ci.org/fosskers/versions)
 [![Hackage](https://img.shields.io/hackage/v/versions.svg?style=flat)](https://hackage.haskell.org/package/versions)
 [![Stackage Nightly](http://stackage.org/package/versions/badge/nightly)](http://stackage.org/nightly/package/versions)
 [![Stackage LTS](http://stackage.org/package/versions/badge/lts)](http://stackage.org/lts/package/versions)
@@ -28,7 +27,7 @@
 
 Usage
 -----
-In general, `parseV` is the function you want. It attempts to parse a given
+In general, `versioning` is the function you want. It attempts to parse a given
 Text using the three individual parsers, `semver`, `version` and `mess`. If
 one fails, it tries the next. If you know you only want to parse one
 specific version type, use that parser directly (e.g. `semver`).
diff --git a/test/Test.hs b/test/Test.hs
--- a/test/Test.hs
+++ b/test/Test.hs
@@ -1,21 +1,19 @@
-{-# LANGUAGE OverloadedStrings #-}
+{-# LANGUAGE OverloadedStrings, NoImplicitPrelude #-}
 
 module Main where
 
-import Data.Char
-import Data.Either (isRight, isLeft)
-import Data.Foldable (fold)
-import Data.List (groupBy)
-import Data.Monoid ((<>))
-import Data.Text (Text, unpack, pack)
-import Data.Versions
-import Lens.Micro
-import Test.QuickCheck
-import Test.QuickCheck.Checkers
-import Test.QuickCheck.Classes
-import Test.Tasty
-import Test.Tasty.HUnit
-import Test.Tasty.QuickCheck
+import           BasePrelude hiding (Version, try)
+import qualified Data.Text as T
+import           Data.Versions
+import           Lens.Micro
+import           Test.QuickCheck
+import           Test.QuickCheck.Checkers
+import           Test.QuickCheck.Classes
+import           Test.Tasty
+import           Test.Tasty.HUnit
+import           Test.Tasty.QuickCheck
+import           Text.Megaparsec
+import           Text.Megaparsec.Char
 
 ---
 
@@ -37,7 +35,7 @@
 
 instance Arbitrary VUnit where
   arbitrary = frequency [ (1, Digits . (+ 1) <$> arbitrary) , (1, s) ]
-    where s = Str . pack . map unletter <$> resize 10 (listOf1 arbitrary)
+    where s = Str . T.pack . map unletter <$> resize 10 (listOf1 arbitrary)
 
 instance EqProp VUnit where
   a =-= b = eq a b
@@ -55,31 +53,31 @@
   a =-= b = eq a b
 
 -- | These don't need to parse as a SemVer.
-goodVers :: [Text]
+goodVers :: [T.Text]
 goodVers = [ "1", "1.2", "1.0rc0", "1.0rc1", "1.1rc1", "1.58.0-3",  "44.0.2403.157-1"
            , "0.25-2",  "8.u51-1", "21-2", "7.1p1-1", "20150826-1", "1:0.10.16-3"
            ]
 
-messes :: [Text]
+messes :: [T.Text]
 messes = [ "10.2+0.93+1-1", "003.03-3", "002.000-7", "20.26.1_0-2" ]
 
-messComps :: [Text]
+messComps :: [T.Text]
 messComps = [ "10.2+0.93+1-1", "10.2+0.93+1-2", "10.2+0.93+2-1"
             , "10.2+0.94+1-1", "10.3+0.93+1-1", "11.2+0.93+1-1", "12"
             ]
 
-badSemVs :: [Text]
+badSemVs :: [T.Text]
 badSemVs = [ "1", "1.2", "1.2.3+a1b2bc3.1-alpha.2", "a.b.c", "1.01.1"
            , "1.2.3+a1b!2c3.1"
            ]
 
-goodSemVs :: [Text]
+goodSemVs :: [T.Text]
 goodSemVs = [ "0.1.0", "1.2.3", "1.2.3-1", "1.2.3-alpha", "1.2.3-alpha.2"
             , "1.2.3+a1b2c3.1", "1.2.3-alpha.2+a1b2c3.1"
             ]
 
 -- | The exact example from `http://semver.org`
-semverOrd :: [Text]
+semverOrd :: [T.Text]
 semverOrd = [ "1.0.0-alpha", "1.0.0-alpha.1", "1.0.0-alpha.beta"
             , "1.0.0-beta", "1.0.0-beta.2", "1.0.0-beta.11", "1.0.0-rc.1"
             , "1.0.0"
@@ -90,10 +88,10 @@
 -- make this necessary, meaning `cabal` can't be simplified to ignore it.
 -- Logically, these are the same package, but for those 5 packages, they
 -- aren't.
-cabalOrd :: [Text]
+cabalOrd :: [T.Text]
 cabalOrd = [ "0.2", "0.2.0", "0.2.0.0" ]
 
-versionOrd :: [Text]
+versionOrd :: [T.Text]
 versionOrd = [ "0.9.9.9", "1.0.0.0", "1.0.0.1", "2" ]
 
 suite :: TestTree
@@ -111,55 +109,55 @@
   , testGroup "Unit Tests"
     [ testGroup "(Ideal) Semantic Versioning"
       [ testGroup "Bad Versions (shouldn't parse)" $
-        map (\s -> testCase (unpack s) $ assertBool "A bad version parsed" $ isLeft $ semver s) badSemVs
+        map (\s -> testCase (T.unpack s) $ assertBool "A bad version parsed" $ isLeft $ semver s) badSemVs
       , testGroup "Good Versions (should parse)" $
-        map (\s -> testCase (unpack s) $ isomorphSV s) goodSemVs
+        map (\s -> testCase (T.unpack s) $ isomorphSV s) goodSemVs
       , testGroup "Comparisons" $
         testCase "1.2.3-alpha.2 == 1.2.3-alpha.2+a1b2c3.1"
         (assertBool "Equality test of two complicated SemVers failed"
          $ semver "1.2.3-alpha.2" == semver "1.2.3-alpha.2+a1b2c3.1") :
-        map (\(a,b) -> testCase (unpack $ a <> " < " <> b) $ comp semver a b)
+        map (\(a,b) -> testCase (T.unpack $ a <> " < " <> b) $ comp semver a b)
         (zip semverOrd $ tail semverOrd)
       ]
     , testGroup "(General) Versions"
       [ testGroup "Good Versions" $
-        map (\s -> testCase (unpack s) $ isomorphV s) goodVers
+        map (\s -> testCase (T.unpack s) $ isomorphV s) goodVers
       , testGroup "Comparisons" $
         testCase "1.2-5 < 1.2.3-1" (comp version "1.2-5" "1.2.3-1") :
         testCase "1.0rc1 < 1.0" (comp version "1.0rc1" "1.0") :
         testCase "1.0 < 1:1.0" (comp version "1.0" "1:1.0") :
         testCase "1.1 < 1:1.0" (comp version "1.1" "1:1.0") :
         testCase "1.1 < 1:1.1" (comp version "1.1" "1:1.1") :
-        map (\(a,b) -> testCase (unpack $ a <> " < " <> b) $ comp version a b)
+        map (\(a,b) -> testCase (T.unpack $ a <> " < " <> b) $ comp version a b)
         (zip cabalOrd (tail cabalOrd) <> zip versionOrd (tail versionOrd))
       ]
     , testGroup "(Complex) Mess"
       [ testGroup "Good Versions" $
-        map (\s -> testCase (unpack s) $ isomorphM s) messes
+        map (\s -> testCase (T.unpack s) $ isomorphM s) messes
       , testGroup "Comparisons" $
-        map (\(a,b) -> testCase (unpack $ a <> " < " <> b) $ comp mess a b) $
+        map (\(a,b) -> testCase (T.unpack $ a <> " < " <> b) $ comp mess a b) $
         zip messComps (tail messComps)
       ]
     , testGroup "Mixed Versioning"
       [ testGroup "Identification"
-        [ testCase "1.2.3 is SemVer" $ check $ isSemVer <$> parseV "1.2.3"
-        , testCase "1.2.3-1 is SemVer" $ check $ isSemVer <$> parseV "1.2.3-1"
-        , testCase "1.2.3-1+1 is SemVer" $ check $ isSemVer <$> parseV "1.2.3-1+1"
-        , testCase "1.2.3r1 is Version" $ check $ isVersion <$> parseV "1.2.3r1"
-        , testCase "0.25-2 is Version" $ check $ isVersion <$> parseV "0.25-2"
-        , testCase "1:1.2.3-1 is Version" $ check $ isVersion <$> parseV "1:1.2.3-1"
-        , testCase "1.2.3+1-1 is Mess" $ check $ isMess <$> parseV "1.2.3+1-1"
-        , testCase "000.007-1 is Mess" $ check $ isMess <$> parseV "000.007-1"
-        , testCase "20.26.1_0-2 is Mess" $ check $ isMess <$> parseV "20.26.1_0-2"
+        [ testCase "1.2.3 is SemVer" $ check $ isSemVer <$> versioning "1.2.3"
+        , testCase "1.2.3-1 is SemVer" $ check $ isSemVer <$> versioning "1.2.3-1"
+        , testCase "1.2.3-1+1 is SemVer" $ check $ isSemVer <$> versioning "1.2.3-1+1"
+        , testCase "1.2.3r1 is Version" $ check $ isVersion <$> versioning "1.2.3r1"
+        , testCase "0.25-2 is Version" $ check $ isVersion <$> versioning "0.25-2"
+        , testCase "1:1.2.3-1 is Version" $ check $ isVersion <$> versioning "1:1.2.3-1"
+        , testCase "1.2.3+1-1 is Mess" $ check $ isMess <$> versioning "1.2.3+1-1"
+        , testCase "000.007-1 is Mess" $ check $ isMess <$> versioning "000.007-1"
+        , testCase "20.26.1_0-2 is Mess" $ check $ isMess <$> versioning "20.26.1_0-2"
         ]
       , testGroup "Isomorphisms" $
-        map (\s -> testCase (unpack s) $ isomorph s) $ goodSemVs ++ goodVers ++ messes
+        map (\s -> testCase (T.unpack s) $ isomorph s) $ goodSemVs ++ goodVers ++ messes
       , testGroup "Comparisons"
-        [ testCase "1.2.2r1-1 < 1.2.3-1"   $ comp parseV "1.2.2r1-1" "1.2.3-1"
-        , testCase "1.2.3-1   < 1.2.4r1-1" $ comp parseV "1.2.3-1" "1.2.4r1-1"
-        , testCase "1.2.3-1   < 2+0007-1"  $ comp parseV "1.2.3-1" "2+0007-1"
-        , testCase "1.2.3r1-1 < 2+0007-1"  $ comp parseV "1.2.3r1-1" "2+0007-1"
-        , testCase "1.2-5 < 1.2.3-1"       $ comp parseV "1.2-5" "1.2.3-1"
+        [ testCase "1.2.2r1-1 < 1.2.3-1"   $ comp versioning "1.2.2r1-1" "1.2.3-1"
+        , testCase "1.2.3-1   < 1.2.4r1-1" $ comp versioning "1.2.3-1" "1.2.4r1-1"
+        , testCase "1.2.3-1   < 2+0007-1"  $ comp versioning "1.2.3-1" "2+0007-1"
+        , testCase "1.2.3r1-1 < 2+0007-1"  $ comp versioning "1.2.3r1-1" "2+0007-1"
+        , testCase "1.2-5 < 1.2.3-1"       $ comp versioning "1.2-5" "1.2.3-1"
         ]
       ]
     , testGroup "Lenses and Traversals"
@@ -168,25 +166,29 @@
       , testCase "SemVer - Get patches" patches
       , testCase "Traverse `General` as `Ideal`" noInc
       ]
+    , testGroup "Megaparsec Behaviour"
+      [ testCase "manyTill" $ parse nameGrab "manyTill" "linux-firmware-3.2.14-1-x86_64.pkg.tar.xz" @?= Right "linux-firmware"
+      , testCase "Extracting version" $ parse versionGrab "extraction" "linux-firmware-3.2.14-1-x86_64.pkg.tar.xz" @?= Right(Ideal $ SemVer 3 2 14 [[Digits 1]] [])
+      ]
     ]
   ]
 
 -- | Does pretty-printing return a Versioning to its original form?
-isomorph :: Text -> Assertion
-isomorph t = Right t @=? (prettyV <$> parseV t)
+isomorph :: T.Text -> Assertion
+isomorph t = Right t @=? (prettyV <$> versioning t)
 
 -- | Does pretty-printing return a Version to its original form?
-isomorphV :: Text -> Assertion
+isomorphV :: T.Text -> Assertion
 isomorphV t = Right t @=? (prettyVer <$> version t)
 
 -- | Does pretty-printing return a SemVer to its original form?
-isomorphSV :: Text -> Assertion
+isomorphSV :: T.Text -> Assertion
 isomorphSV t = Right t @=? (prettySemVer <$> semver t)
 
-isomorphM :: Text -> Assertion
+isomorphM :: T.Text -> Assertion
 isomorphM t =  Right t @=? (prettyMess <$> mess t)
 
-comp :: Ord b => (Text -> Either a b) -> Text -> Text -> Assertion
+comp :: Ord b => (T.Text -> Either a b) -> T.Text -> T.Text -> Assertion
 comp f a b = check $ (<) <$> f a <*> f b
 
 check :: Either a Bool -> Assertion
@@ -215,11 +217,20 @@
   where v = General $ Version Nothing [] []
 
 incFromT :: Assertion
-incFromT = (("1.2.3" :: Text) & patch %~ (+ 1)) @?= "1.2.4"
+incFromT = (("1.2.3" :: T.Text) & patch %~ (+ 1)) @?= "1.2.4"
 
 patches :: Assertion
 patches = ps @?= [3,4,5]
-  where ps = (["1.2.3","2.3.4","3.4.5"] :: [Text]) ^.. each . patch
+  where ps = (["1.2.3","2.3.4","3.4.5"] :: [T.Text]) ^.. each . patch
 
 main :: IO ()
 main = defaultMain suite
+
+nameGrab :: Parsec Void T.Text T.Text
+nameGrab = T.pack <$> manyTill anyChar (try finished)
+  where finished = char '-' *> lookAhead digitChar
+
+versionGrab :: Parsec Void T.Text Versioning
+versionGrab = manyTill anyChar (try finished) *> ver
+  where finished = char '-' *> lookAhead digitChar
+        ver = fmap Ideal semver' <|> fmap General version' <|> fmap Complex mess'
diff --git a/versions.cabal b/versions.cabal
--- a/versions.cabal
+++ b/versions.cabal
@@ -1,11 +1,11 @@
--- This file has been generated from package.yaml by hpack version 0.20.0.
+-- This file has been generated from package.yaml by hpack version 0.28.2.
 --
 -- see: https://github.com/sol/hpack
 --
--- hash: ade99e86a1b2ba008cc0e453113e07938d16e488a28e2f5fcdfb8b61e33d7a6c
+-- hash: afb8248e886b4197b3f7e3c3eb5132afb1409a8ac97bcf914795a9a3fd2ffdd7
 
 name:           versions
-version:        3.3.2
+version:        3.4.0
 synopsis:       Types and parsers for software version numbers.
 description:    A library for parsing and comparing software version numbers. We like to give version numbers to our software in a myriad of ways. Some ways follow strict guidelines for incrementing and comparison. Some follow conventional wisdom and are generally self-consistent. Some are just plain asinine. This library provides a means of parsing and comparing /any/ style of versioning, be it a nice Semantic Version like this:
                 .
@@ -17,23 +17,19 @@
                 .
                 Please switch to <http://semver.org Semantic Versioning> if you aren't currently using it. It provides consistency in version incrementing and has the best constraints on comparisons.
 category:       Data
+homepage:       https://gitlab.com/fosskers/versions
 author:         Colin Woodbury
-maintainer:     colingw@gmail.com
+maintainer:     colin@fosskers.ca
 license:        BSD3
 license-file:   LICENSE
 build-type:     Simple
 cabal-version:  >= 1.10
-
 extra-source-files:
     CHANGELOG.md
     README.md
 
-source-repository head
-  type: git
-  location: git://github.com/fosskers/haskell-versions.git
-
 library
-  ghc-options: -fwarn-unused-imports -fwarn-unused-binds -fwarn-name-shadowing -fwarn-unused-matches -fwarn-incomplete-patterns -Wincomplete-uni-patterns
+  ghc-options: -fwarn-unused-imports -fwarn-unused-binds -fwarn-name-shadowing -fwarn-unused-matches -fwarn-incomplete-patterns -fwarn-redundant-constraints -Wincomplete-uni-patterns
   build-depends:
       base >=4.8 && <4.12
     , deepseq >=1.4 && <1.5
@@ -49,15 +45,17 @@
   main-is: Test.hs
   hs-source-dirs:
       test
-  ghc-options: -fwarn-unused-imports -fwarn-unused-binds -fwarn-name-shadowing -fwarn-unused-matches -fwarn-incomplete-patterns -Wincomplete-uni-patterns -threaded -with-rtsopts=-N
+  ghc-options: -fwarn-unused-imports -fwarn-unused-binds -fwarn-name-shadowing -fwarn-unused-matches -fwarn-incomplete-patterns -fwarn-redundant-constraints -Wincomplete-uni-patterns -threaded -with-rtsopts=-N
   build-depends:
       QuickCheck >=2.9 && <2.12
     , base >=4.8 && <4.12
+    , base-prelude
     , checkers >=0.4 && <0.5
+    , megaparsec >=6 && <7
     , microlens >=0.4 && <0.5
     , tasty >=0.10.1.2
     , tasty-hunit >=0.9.2
-    , tasty-quickcheck >=0.8 && <0.10
+    , tasty-quickcheck >=0.8 && <0.11
     , text >=1.2 && <1.3
     , versions
   default-language: Haskell2010
