diff --git a/bench/Main.hs b/bench/Main.hs
--- a/bench/Main.hs
+++ b/bench/Main.hs
@@ -1,7 +1,7 @@
 {-# LANGUAGE OverloadedStrings #-}
 
 -- Module      : Main
--- Copyright   : (c) 2014-2015 Brendan Hay <brendan.g.hay@gmail.com>
+-- Copyright   : (c) 2014-2019 Brendan Hay <brendan.g.hay@gmail.com>
 -- License     : This Source Code Form is subject to the terms of
 --               the Mozilla Public License, v. 2.0.
 --               A copy of the MPL can be found in the LICENSE file or
diff --git a/semver.cabal b/semver.cabal
--- a/semver.cabal
+++ b/semver.cabal
@@ -1,12 +1,12 @@
 name:                  semver
-version:               0.3.3.1
+version:               0.3.4
 synopsis:              Representation, manipulation, and de/serialisation of Semantic Versions.
 homepage:              https://github.com/brendanhay/semver
 license:               OtherLicense
 license-file:          LICENSE
 author:                Brendan Hay
 maintainer:            Brendan Hay <brendan.g.hay@gmail.com>
-copyright:             Copyright (c) 2014-2014 Brendan Hay
+copyright:             Copyright (c) 2014-2019 Brendan Hay
 category:              Data
 build-type:            Simple
 extra-source-files:    README.md
@@ -38,6 +38,7 @@
           attoparsec >= 0.10
         , base       >= 4.5  && < 5.0
         , deepseq    >= 1.1
+        , hashable   >= 1.1.1
         , text       >= 0.11
 
 benchmark semver-bench
diff --git a/src/Data/SemVer.hs b/src/Data/SemVer.hs
--- a/src/Data/SemVer.hs
+++ b/src/Data/SemVer.hs
@@ -1,5 +1,5 @@
 -- Module      : Data.SemVer
--- Copyright   : (c) 2014-2015 Brendan Hay <brendan.g.hay@gmail.com>
+-- Copyright   : (c) 2014-2019 Brendan Hay <brendan.g.hay@gmail.com>
 -- License     : This Source Code Form is subject to the terms of
 --               the Mozilla Public License, v. 2.0.
 --               A copy of the MPL can be found in the LICENSE file or
diff --git a/src/Data/SemVer/Delimited.hs b/src/Data/SemVer/Delimited.hs
--- a/src/Data/SemVer/Delimited.hs
+++ b/src/Data/SemVer/Delimited.hs
@@ -2,7 +2,7 @@
 {-# LANGUAGE RecordWildCards   #-}
 
 -- Module      : Data.SemVer.Delimited
--- Copyright   : (c) 2014-2015 Brendan Hay <brendan.g.hay@gmail.com>
+-- Copyright   : (c) 2014-2019 Brendan Hay <brendan.g.hay@gmail.com>
 -- License     : This Source Code Form is subject to the terms of
 --               the Mozilla Public License, v. 2.0.
 --               A copy of the MPL can be found in the LICENSE file or
diff --git a/src/Data/SemVer/Internal.hs b/src/Data/SemVer/Internal.hs
--- a/src/Data/SemVer/Internal.hs
+++ b/src/Data/SemVer/Internal.hs
@@ -2,7 +2,7 @@
 {-# LANGUAGE RecordWildCards   #-}
 
 -- Module      : Data.SemVer.Internal
--- Copyright   : (c) 2014-2015 Brendan Hay <brendan.g.hay@gmail.com>
+-- Copyright   : (c) 2014-2019 Brendan Hay <brendan.g.hay@gmail.com>
 -- License     : This Source Code Form is subject to the terms of
 --               the Mozilla Public License, v. 2.0.
 --               A copy of the MPL can be found in the LICENSE file or
@@ -18,6 +18,7 @@
 import           Control.Monad
 import           Data.Attoparsec.Text
 import           Data.Function        (on)
+import           Data.Hashable
 import           Data.List            (intersperse)
 import           Data.Monoid
 import           Data.Text            (Text)
@@ -53,8 +54,8 @@
         -- Note: Contrary to 'List's, @[] `compare` [xs]@ equals to @GT@
         release =
             case (_versionRelease a, _versionRelease b) of
-                ([], _) -> GT
-                (_, []) -> LT
+                ([], _:_) -> GT
+                (_:_, []) -> LT
                 (x, y)  -> x `compare` y
 
 instance NFData Version where
@@ -65,6 +66,14 @@
         `seq` rnf _versionRelease
         `seq` rnf _versionMeta
 
+instance Hashable Version where
+    hashWithSalt s Version {..} =
+        s `hashWithSalt` _versionMajor
+          `hashWithSalt` _versionMinor
+          `hashWithSalt` _versionPatch
+          `hashWithSalt` _versionRelease
+          `hashWithSalt` _versionMeta
+
 -- | A type representing an individual identifier from the release
 -- or metadata components of a 'Version'.
 --
@@ -88,6 +97,10 @@
 instance NFData Identifier where
     rnf (INum  n) = rnf n
     rnf (IText t) = rnf t
+
+instance Hashable Identifier where
+    hashWithSalt s (INum  n) = s `hashWithSalt` (0 :: Int) `hashWithSalt` n
+    hashWithSalt s (IText t) = s `hashWithSalt` (1 :: Int) `hashWithSalt` t
 
 identifierParser :: Parser () -> Parser Identifier
 identifierParser p =
diff --git a/test/Main.hs b/test/Main.hs
--- a/test/Main.hs
+++ b/test/Main.hs
@@ -1,7 +1,7 @@
 {-# LANGUAGE OverloadedStrings #-}
 
 -- Module      : Main
--- Copyright   : (c) 2014-2015 Brendan Hay <brendan.g.hay@gmail.com>
+-- Copyright   : (c) 2014-2019 Brendan Hay <brendan.g.hay@gmail.com>
 -- License     : This Source Code Form is subject to the terms of
 --               the Mozilla Public License, v. 2.0.
 --               A copy of the MPL can be found in the LICENSE file or
@@ -49,6 +49,16 @@
         , testCase "1.2.3-beta.1+sha.exp.dc2 < 1.2.3+sha.2ac" $
             true (sv123beta1shaexpdc2 < sv123sha2ac)
         ]
+    , testGroup "equality"
+        [ testCase "0.0.0 == 0.0.0" $
+            sv000 @=? sv000
+        , testCase "compare 0.0.0 0.0.0 == EQ" $
+            (sv000 `compare` sv000) @=? EQ
+        , testCase "1.2.3 /= 1.2.3+sha.2ac" $
+            (sv123 /= sv123sha2ac) @=? True
+        , testCase "compare 1.2.3 1.2.3+sha.2ac == EQ" $
+            (sv123 `compare` sv123sha2ac) @=? EQ
+        ]
     ]
 
 iso :: Text -> TestTree
@@ -66,6 +76,7 @@
 sv101               = sv "1.0.1"
 sv110               = sv "1.1.0"
 sv200               = sv "2.0.0"
+sv123               = sv "1.2.3"
 sv123sha2ac         = sv "1.2.3+sha.2ac"
 sv123beta1shaexpdc2 = sv "1.2.3-beta.1+sha.exp.dc2"
 
