diff --git a/Data/Versions.hs b/Data/Versions.hs
--- a/Data/Versions.hs
+++ b/Data/Versions.hs
@@ -1,11 +1,12 @@
-{-# LANGUAGE Rank2Types #-}
+{-# LANGUAGE CPP               #-}
+{-# LANGUAGE DeriveAnyClass    #-}
+{-# LANGUAGE DeriveGeneric     #-}
 {-# LANGUAGE OverloadedStrings #-}
-{-# LANGUAGE DeriveGeneric, DeriveAnyClass #-}
-{-# LANGUAGE CPP #-}
+{-# LANGUAGE Rank2Types        #-}
 
 -- |
 -- Module    : Data.Versions
--- Copyright : (c) Colin Woodbury, 2015 - 2018
+-- Copyright : (c) Colin Woodbury, 2015 - 2019
 -- License   : BSD3
 -- Maintainer: Colin Woodbury <colingw@gmail.com>
 --
@@ -13,10 +14,9 @@
 --
 -- We like to give version numbers to our software in a myriad of different
 -- 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:
+-- 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:
 --
 -- > 1.2.3-r1+git123
 --
@@ -24,16 +24,15 @@
 --
 -- > 2:10.2+0.0093r3+1-1
 --
--- 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.
+-- 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.
 --
 -- == Using the Parsers
--- 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`).
+-- 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`).
 
 module Data.Versions
     (
@@ -82,28 +81,28 @@
 import           Text.Megaparsec.Char
 import qualified Text.Megaparsec.Char.Lexer as L
 
-#if __GLASGOW_HASKELL__ < 841
-import Data.Semigroup
+#if !MIN_VERSION_base(4,11,0)
+import           Data.Semigroup
 #endif
 
 ---
 
--- | A top-level Versioning type. Acts as a wrapper for the more specific
--- types. This allows each subtype to have its own parser, and for said
--- parsers to be composed. This is useful for specifying custom behaviour
--- for when a certain parser fails.
+-- | A top-level Versioning type. Acts as a wrapper for the more specific types.
+-- This allows each subtype to have its own parser, and for said parsers to be
+-- composed. This is useful for specifying custom behaviour for when a certain
+-- parser fails.
 data Versioning = Ideal SemVer | General Version | Complex Mess
   deriving (Eq,Show,Generic,NFData,Hashable)
 
 -- | Comparison of @Ideal@s is always well defined.
 --
--- If comparison of @General@s is well-defined, then comparison
--- of @Ideal@ and @General@ is well-defined, as there exists a perfect
--- mapping from @Ideal@ to @General@.
+-- If comparison of @General@s is well-defined, then comparison of @Ideal@ and
+-- @General@ is well-defined, as there exists a perfect mapping from @Ideal@ to
+-- @General@.
 --
 -- If comparison of @Complex@es is well-defined, then comparison of @General@
--- and @Complex@ is well defined for the same reason.
--- This implies comparison of @Ideal@ and @Complex@ is also well-defined.
+-- and @Complex@ is well defined for the same reason. This implies comparison of
+-- @Ideal@ and @Complex@ is also well-defined.
 instance Ord Versioning where
   compare (Ideal s)     (Ideal s')    = compare s s'
   compare (General v)   (General v')  = compare v v'
@@ -182,17 +181,17 @@
 
 _Ideal :: Traversal' Versioning SemVer
 _Ideal f (Ideal s) = Ideal <$> f s
-_Ideal _ v = pure v
+_Ideal _ v         = pure v
 {-# INLINE _Ideal #-}
 
 _General :: Traversal' Versioning Version
 _General f (General v) = General <$> f v
-_General _ v = pure v
+_General _ v           = pure v
 {-# INLINE _General #-}
 
 _Complex :: Traversal' Versioning Mess
 _Complex f (Complex m) = Complex <$> f m
-_Complex _ v = pure v
+_Complex _ v           = pure v
 {-# INLINE _Complex #-}
 
 -- | Simple Lenses compatible with both lens and microlens.
@@ -201,13 +200,13 @@
 -- | Simple Traversals compatible with both lens and microlens.
 type Traversal' s a = forall f. Applicative f => (a -> f a) -> s -> f s
 
--- | Version types which sanely and safely yield `SemVer`-like information
--- about themselves. For instances other than `SemVer` itself however,
--- these optics may /not/ yield anything, depending on the actual value being
--- traversed. Hence, the optics here are all `Traversal'`s.
+-- | Version types which sanely and safely yield `SemVer`-like information about
+-- themselves. For instances other than `SemVer` itself however, these optics
+-- may /not/ yield anything, depending on the actual value being traversed.
+-- Hence, the optics here are all `Traversal'`s.
 --
--- Consider the `Version` @1.2.3.4.5@. We can imagine wanting to increment
--- the minor number:
+-- Consider the `Version` @1.2.3.4.5@. We can imagine wanting to increment the
+-- minor number:
 --
 -- @
 -- λ "1.2.3.4.5" & minor %~ (+ 1)
@@ -318,9 +317,9 @@
   semantic = ($)
   {-# INLINE semantic #-}
 
--- | A single unit of a Version. May be digits or a string of characters.
--- Groups of these are called `VChunk`s, and are the identifiers separated
--- by periods in the source.
+-- | A single unit of a Version. May be digits or a string of characters. Groups
+-- of these are called `VChunk`s, and are the identifiers separated by periods
+-- in the source.
 data VUnit = Digits Word | Str T.Text deriving (Eq,Show,Read,Ord,Generic,NFData,Hashable)
 
 instance Semigroup VUnit where
@@ -346,12 +345,12 @@
 
 _Digits :: Traversal' VUnit Word
 _Digits f (Digits i) = Digits <$> f i
-_Digits _ v = pure v
+_Digits _ v          = pure v
 {-# INLINE _Digits #-}
 
 _Str :: Traversal' VUnit T.Text
 _Str f (Str t) = Str . (\t' -> bool t t' (T.all isAlpha t')) <$> f t
-_Str _ v = pure v
+_Str _ v       = pure v
 {-# INLINE _Str #-}
 
 -- | A logical unit of a version number. Can consist of multiple letters
@@ -409,21 +408,22 @@
 
   -- | If one side has run out of chunks to compare but the other hasn't,
   -- the other must be newer.
-  compare (Version _ _ _)  (Version _ [] _) = GT
-  compare (Version _ [] _) (Version _ _ _)  = LT
+  compare Version{}  (Version _ [] _) = GT
+  compare (Version _ [] _) Version{}  = LT
 
-  -- | The usual case. If first VChunks of each Version is equal, then we
-  -- keep recursing. Otherwise, we don't need to check further. Consider @1.2@
+  -- | The usual case. If first VChunks of each Version is equal, then we keep
+  -- recursing. Otherwise, we don't need to check further. Consider @1.2@
   -- compared to @1.1.3.4.5.6@.
   compare (Version _ (a:as) rs) (Version _ (b:bs) rs') = case f a b of
     EQ  -> compare (Version Nothing as rs) (Version Nothing bs rs')
     res -> res
     where f [] [] = EQ
 
-          -- | Opposite of the above. If we've recursed this far and one side has
-          -- fewer chunks, it must be the "greater" version. A Chunk break only occurs in
-          -- a switch from digits to letters and vice versa, so anything "extra" must be
-          -- an @rc@ marking or similar. Consider @1.1@ compared to @1.1rc1@.
+          -- | Opposite of the above. If we've recursed this far and one side
+          -- has fewer chunks, it must be the "greater" version. A Chunk break
+          -- only occurs in a switch from digits to letters and vice versa, so
+          -- anything "extra" must be an @rc@ marking or similar. Consider @1.1@
+          -- compared to @1.1rc1@.
           f [] _  = GT
           f _ []  = LT
 
@@ -468,18 +468,17 @@
 epoch f v = fmap (\ve -> v { _vEpoch = ve }) (f $ _vEpoch v)
 {-# INLINE epoch #-}
 
--- | A (Complex) Mess.
--- This is a /descriptive/ parser, based on examples of stupidly
--- crafted version numbers used in the wild.
+-- | A (Complex) Mess. This is a /descriptive/ parser, based on examples of
+-- stupidly crafted version numbers used in the wild.
 --
--- Groups of letters/numbers, separated by a period, can be
--- further separated by the symbols @_-+:@
+-- Groups of letters/numbers, separated by a period, can be further separated by
+-- the symbols @_-+:@
 --
--- Unfortunately, @VChunk@s cannot be used here, as some developers have
--- numbers like @1.003.04@ which make parsers quite sad.
+-- Unfortunately, @VChunk@s cannot be used here, as some developers have numbers
+-- like @1.003.04@ which make parsers quite sad.
 --
--- Not guaranteed to have well-defined ordering (@Ord@) behaviour,
--- but so far internal tests show consistency.
+-- Not guaranteed to have well-defined ordering (@Ord@) behaviour, but so far
+-- internal tests show consistency.
 data Mess = VLeaf [T.Text] | VNode [T.Text] VSep Mess deriving (Eq,Show,Generic,NFData,Hashable)
 
 instance Ord Mess where
@@ -523,8 +522,8 @@
   semantic _ v = pure v
   {-# INLINE semantic #-}
 
--- | Developers use a number of symbols to seperate groups of digits/letters
--- in their version numbers. These are:
+-- | Developers use a number of symbols to seperate groups of digits/letters in
+-- their version numbers. These are:
 --
 -- * A colon (:). Often denotes an "epoch".
 -- * A hyphen (-).
diff --git a/test/Test.hs b/test/Test.hs
--- a/test/Test.hs
+++ b/test/Test.hs
@@ -1,5 +1,8 @@
-{-# LANGUAGE OverloadedStrings, NoImplicitPrelude #-}
+{-# LANGUAGE NoImplicitPrelude #-}
+{-# LANGUAGE OverloadedStrings #-}
 
+{-# OPTIONS_GHC -fno-warn-orphans #-}
+
 module Main where
 
 import           BasePrelude hiding (Version, try)
@@ -27,8 +30,8 @@
 simplify :: [VUnit] -> [VUnit]
 simplify = map fold . groupBy f
   where f (Digits _) (Digits _) = True
-        f (Str _) (Str _) = True
-        f _ _ = False
+        f (Str _) (Str _)       = True
+        f _ _                   = False
 
 instance EqProp SemVer where
   a =-= b = eq a b
@@ -98,13 +101,13 @@
 suite = testGroup "Tests"
   [ testGroup "Property Tests"
     [ testGroup "SemVer - Monoid" $
-      map (\(name, test) -> testProperty name test) . unbatch $ monoid (SemVer 1 2 3 [] [])
+      map (uncurry testProperty) . unbatch $ monoid (SemVer 1 2 3 [] [])
     , testProperty "SemVer - Arbitrary" $ \a -> isRight . fmap (== a) $ semver (prettySemVer a)
     , testProperty "Version - Arbitrary" $ \a -> isRight . fmap (== a) $ version (prettyVer a)
     -- , testGroup "Version - Monoid" $
     --   map (\(name, test) -> testProperty name test) . unbatch $ monoid (Version (Just 1) [[digits 2], [digits 3]])
     , testGroup "VUnit - Monoid" $
-      map (\(name, test) -> testProperty name test) . unbatch $ monoid (Digits 0)
+      map (uncurry testProperty) . unbatch $ monoid (Digits 0)
     ]
   , testGroup "Unit Tests"
     [ testGroup "(Ideal) Semantic Versioning"
@@ -199,15 +202,15 @@
 
 isSemVer :: Versioning -> Bool
 isSemVer (Ideal _) = True
-isSemVer _ = False
+isSemVer _         = False
 
 isVersion :: Versioning -> Bool
 isVersion (General _) = True
-isVersion _ = False
+isVersion _           = False
 
 isMess :: Versioning -> Bool
 isMess (Complex _) = True
-isMess _ = False
+isMess _           = False
 
 incPatch :: Assertion
 incPatch = (v1 & patch %~ (+ 1)) @?= v2
diff --git a/versions.cabal b/versions.cabal
--- a/versions.cabal
+++ b/versions.cabal
@@ -1,13 +1,13 @@
 cabal-version: 1.12
 
--- This file has been generated from package.yaml by hpack version 0.30.0.
+-- This file has been generated from package.yaml by hpack version 0.31.1.
 --
 -- see: https://github.com/sol/hpack
 --
--- hash: c88c48a70659eb4789fc7f8c40a392f43def7f65ede9b0a91be6cdc1e1eaac33
+-- hash: 0111f82d056307121e5cb513988396b08a74ec75fc3c29455a1bd6de361afc1c
 
 name:           versions
-version:        3.5.0
+version:        3.5.1
 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:
                 .
@@ -30,13 +30,13 @@
     README.md
 
 library
-  ghc-options: -fwarn-unused-imports -fwarn-unused-binds -fwarn-name-shadowing -fwarn-unused-matches -fwarn-incomplete-patterns -fwarn-redundant-constraints -Wincomplete-uni-patterns
+  ghc-options: -Wall -Wincomplete-record-updates -Wincomplete-uni-patterns -Wredundant-constraints
   build-depends:
-      base >=4.8 && <4.12
-    , deepseq >=1.4 && <1.5
-    , hashable >=1.2 && <1.3
-    , megaparsec >=7 && <8
-    , text >=1.2 && <1.3
+      base >=4.8 && <4.13
+    , deepseq >=1.4
+    , hashable >=1.2
+    , megaparsec >=7
+    , text >=1.2
   exposed-modules:
       Data.Versions
   default-language: Haskell2010
@@ -46,17 +46,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 -fwarn-redundant-constraints -Wincomplete-uni-patterns -threaded -with-rtsopts=-N
+  ghc-options: -Wall -Wincomplete-record-updates -Wincomplete-uni-patterns -Wredundant-constraints -threaded -with-rtsopts=-N
   build-depends:
-      QuickCheck >=2.9 && <2.13
-    , base >=4.8 && <4.12
+      QuickCheck >=2.9
+    , base >=4.8 && <4.13
     , base-prelude
-    , checkers >=0.4 && <0.5
-    , megaparsec >=7 && <8
-    , microlens >=0.4 && <0.5
+    , checkers >=0.4
+    , megaparsec >=7
+    , microlens >=0.4
     , tasty >=0.10.1.2
     , tasty-hunit >=0.9.2
-    , tasty-quickcheck >=0.8 && <0.11
-    , text >=1.2 && <1.3
+    , tasty-quickcheck >=0.8
+    , text >=1.2
     , versions
   default-language: Haskell2010
