diff --git a/linear.cabal b/linear.cabal
--- a/linear.cabal
+++ b/linear.cabal
@@ -1,6 +1,6 @@
 name:          linear
 category:      Math, Algebra
-version:       1.3
+version:       1.3.1
 license:       BSD3
 cabal-version: >= 1.8
 license-file:  LICENSE
@@ -31,13 +31,14 @@
 library
   build-depends:
     base                 >= 4.5   && < 5,
+    binary               >= 0.5   && < 0.8,
     containers           >= 0.4   && < 0.6,
     distributive         >= 0.2.2 && < 1,
     ghc-prim,
     hashable             >= 1.1   && < 1.3,
     reflection           >= 1.3.2 && < 2,
     semigroups           >= 0.9   && < 1,
-    semigroupoids        >= 3     && < 4,
+    semigroupoids        >= 3     && < 5,
     tagged               >= 0.4.4 && < 1,
     template-haskell     >= 2.7   && < 3.0,
     transformers         >= 0.2   && < 0.4,
@@ -47,6 +48,7 @@
   exposed-modules:
     Linear
     Linear.Affine
+    Linear.Binary
     Linear.Conjugate
     Linear.Core
     Linear.Epsilon
@@ -84,11 +86,13 @@
 test-suite UnitTests
   type:           exitcode-stdio-1.0
   main-is:        UnitTests.hs
-  other-modules:  Plucker
+  other-modules:  Plucker, Binary
   ghc-options:    -Wall -Werror -threaded
   hs-source-dirs: tests
   build-depends:
     base,
+    binary,
+    bytestring,
     test-framework >= 0.8,
     test-framework-hunit >= 0.3,
     HUnit >= 1.2.5,
diff --git a/src/Linear/Affine.hs b/src/Linear/Affine.hs
--- a/src/Linear/Affine.hs
+++ b/src/Linear/Affine.hs
@@ -1,6 +1,7 @@
 {-# LANGUAGE CPP #-}
 {-# LANGUAGE FlexibleContexts #-}
 {-# LANGUAGE GeneralizedNewtypeDeriving #-}
+{-# LANGUAGE DeriveTraversable #-}
 {-# LANGUAGE TypeFamilies #-}
 #if defined(__GLASGOW_HASKELL__) && __GLASGOW_HASKELL__ >= 702
 {-# LANGUAGE Trustworthy #-}
diff --git a/src/Linear/Binary.hs b/src/Linear/Binary.hs
new file mode 100644
--- /dev/null
+++ b/src/Linear/Binary.hs
@@ -0,0 +1,15 @@
+-- | Serialization of statically-sized types with the "Data.Binary"
+-- library.
+module Linear.Binary where
+import Control.Applicative
+import Data.Binary
+import Data.Foldable (Foldable, traverse_)
+import Data.Traversable (Traversable, sequenceA)
+
+-- | Serialize a linear type.
+putLinear :: (Binary a, Foldable t) => t a -> Put
+putLinear = traverse_ put
+
+-- | Deserialize a linear type.
+getLinear :: (Binary a, Applicative t, Traversable t) => Get (t a)
+getLinear = sequenceA $ pure get
diff --git a/src/Linear/Metric.hs b/src/Linear/Metric.hs
--- a/src/Linear/Metric.hs
+++ b/src/Linear/Metric.hs
@@ -21,6 +21,10 @@
 import Data.Foldable as Foldable
 import Data.Functor.Identity
 import Data.Vector (Vector)
+import Data.IntMap (IntMap)
+import Data.Map (Map)
+import Data.HashMap.Strict (HashMap)
+import Data.Hashable (Hashable)
 import Linear.Epsilon
 import Linear.Vector
 
@@ -64,6 +68,12 @@
 
 instance Metric Identity where
   dot (Identity x) (Identity y) = x * y
+
+instance Metric IntMap
+
+instance Ord k => Metric (Map k)
+
+instance (Hashable k, Eq k) => Metric (HashMap k)
 
 instance Metric Vector
 
diff --git a/src/Linear/V.hs b/src/Linear/V.hs
--- a/src/Linear/V.hs
+++ b/src/Linear/V.hs
@@ -4,7 +4,7 @@
 {-# LANGUAGE Rank2Types #-}
 {-# LANGUAGE EmptyDataDecls #-}
 {-# LANGUAGE MultiParamTypeClasses, FlexibleContexts, FlexibleInstances, UndecidableInstances #-}
-#if defined(__GLASGOW_HASKELL__) && __GLASGOW_HASKELL__ >= 706
+#if defined(__GLASGOW_HASKELL__) && __GLASGOW_HASKELL__ >= 707
 {-# LANGUAGE DataKinds #-}
 {-# LANGUAGE PolyKinds #-}
 #define USE_TYPE_LITS 1
@@ -65,8 +65,8 @@
 {-# INLINE dim #-}
 
 #ifdef USE_TYPE_LITS
-instance SingRep n Integer => Dim (n :: Nat) where
-  reflectDim _ = fromInteger $ withSing $ \(x :: Sing n) -> fromSing x
+instance KnownNat n => Dim (n :: Nat) where
+  reflectDim = fromInteger . natVal
   {-# INLINE reflectDim #-}
 #endif
 
diff --git a/tests/Binary.hs b/tests/Binary.hs
new file mode 100644
--- /dev/null
+++ b/tests/Binary.hs
@@ -0,0 +1,20 @@
+module Binary (tests) where
+import Control.Applicative
+import Data.Binary.Put
+import Data.Binary.Get
+import Linear
+import qualified Data.ByteString.Lazy as BS
+import Linear.Binary
+import Test.HUnit
+
+originalVecs :: (V3 Float, V2 Char)
+originalVecs = (V3 1 2 3, V2 'a' 'b')
+
+bytes :: BS.ByteString
+bytes = runPut $ do putLinear $ fst originalVecs
+                    putLinear $ snd originalVecs
+
+tests :: Test
+tests = test [ "Serialized length" ~: BS.length bytes ~?= 3*13+2
+             , "Deserialization" ~: deserialized ~?= originalVecs ]
+  where deserialized = runGet ((,) <$> getLinear <*> getLinear) bytes
diff --git a/tests/UnitTests.hs b/tests/UnitTests.hs
--- a/tests/UnitTests.hs
+++ b/tests/UnitTests.hs
@@ -2,9 +2,11 @@
 import Test.Framework (defaultMain, testGroup, Test)
 import Test.Framework.Providers.HUnit
 import qualified Plucker
+import qualified Binary
 
 tests :: [Test]
-tests = [ testGroup "Plucker" $ hUnitTestToTests Plucker.tests ]
+tests = [ testGroup "Plucker" $ hUnitTestToTests Plucker.tests 
+        , testGroup "Binary" $ hUnitTestToTests Binary.tests ]
 
 main :: IO ()
 main = defaultMain tests
